42 std::string included_file;
43 if ( p.
down(
"file") ) {
44 included_file = get_included_file(p);
47 this->generate_input_error(p, array,
"Missing key 'file' defines including input file.",
false);
51 unsigned int n_head_lines = 0;
52 if ( p.
down(
"n_head_lines") ) {
56 catch (ExcInputError & e) {
58 e << EI_InputType(
"number of lines to skip");
65 stringstream separator;
66 if ( p.
down(
"separator") ) {
70 catch (ExcInputError & e) {
72 e << EI_InputType(
"invalid separator of included CSV file");
82 CSVTokenizer tok( fp, separator.str() );
86 if ((abstract_type != NULL) && (record_name.size() <= 12)) {
88 this->generate_input_error(p, array,
89 "Missing record descendant in definition of tag in CSV include of Abstract type. Tag must be in format '!include_csv:Descendant_Name'!",
93 (abstract_type->get_descendant(record_name.substr(12))) : (array->
get_sub_type());
96 csv_columns_map_.clear();
97 if ( p.
down(
"format") ) {
99 csv_subtree_depth_ = p.
path_.size();
100 item_storage = make_storage(p, &sub_type);
101 }
catch (ExcMultipleDefinitionCsvColumn &e) {
102 e << EI_File(tok.f_name());
107 this->generate_input_error(p, array,
"Missing key 'format' defines mapping column of CSV file to input subtree.",
false);
112 it = csv_columns_map_.end(); --it;
113 unsigned int max_column_index = it->first;
115 unsigned int n_lines = tok.get_n_lines() - n_head_lines;
116 tok.skip_header(n_head_lines);
118 std::set<unsigned int> unused_columns;
119 for(
unsigned int arr_item=0; arr_item < n_lines; ++arr_item) {
122 for (i_col=0; !tok.eol(); ++i_col, ++tok) {
123 it = csv_columns_map_.find(i_col);
124 if (it != csv_columns_map_.end()) {
125 switch (it->second.data_type) {
126 case IncludeDataTypes::type_int: {
129 val = tok.get_int_val();
130 }
catch (ExcWrongCsvFormat &e) {
131 e << EI_Specification(
"Wrong integer value");
137 if ( !int_type->
match(val) ) {
138 THROW( ExcWrongCsvFormat() << EI_Specification(
"Integer value out of bounds")
139 << EI_TokenizerMsg(tok.position_msg()) << EI_ErrorAddress(p.
as_string()) );
141 set_storage_from_csv( i_col, item_storage,
new StorageInt(val) );
144 case IncludeDataTypes::type_double: {
147 val = tok.get_double_val();
148 }
catch (ExcWrongCsvFormat &e) {
154 if ( !double_type->
match(val) ) {
155 THROW( ExcWrongCsvFormat() << EI_Specification(
"Double value out of bounds")
156 << EI_TokenizerMsg(tok.position_msg()) << EI_ErrorAddress(p.
as_string()) );
158 set_storage_from_csv( i_col, item_storage,
new StorageDouble(val) );
161 case IncludeDataTypes::type_bool: {
164 val = tok.get_int_val();
165 }
catch (ExcWrongCsvFormat &e) {
166 e << EI_Specification(
"Wrong boolean value");
170 set_storage_from_csv( i_col, item_storage,
new StorageBool(val) );
173 case IncludeDataTypes::type_string: {
175 set_storage_from_csv( i_col, item_storage,
new StorageString(tok.get_string_val()) );
176 }
catch (ExcWrongCsvFormat &e) {
177 e << EI_Specification(
"Wrong string value");
183 case IncludeDataTypes::type_sel: {
186 std::string item_name = tok.get_string_val();
188 set_storage_from_csv( i_col, item_storage,
new StorageInt(val) );
189 }
catch (ExcWrongCsvFormat &e) {
190 e << EI_Specification(
"Wrong selection value");
193 }
catch (Type::Selection::ExcSelectionKeyNotFound &exc) {
194 THROW( ExcWrongCsvFormat() << EI_Specification(
"Wrong selection value")
195 << EI_TokenizerMsg(tok.position_msg()) << EI_ErrorAddress(p.
as_string()) );
202 unused_columns.insert(i_col);
205 if ( max_column_index > (i_col-1) ) {
206 this->generate_input_error(p, array,
"Count of columns in CSV file is less than expected index, defined on input.",
false);
212 if (unused_columns.size()) {
214 for (std::set<unsigned int>::iterator it=unused_columns.begin(); it!=unused_columns.end(); ++it)
216 WarningOut().fmt(
"Unused columns: {}\nin imported CSV input file: {}\n", ss.str(), tok.f_name());
218 return storage_array;
221 this->generate_input_error(p, array,
"Invalid definition of CSV include.",
false);
230 return this->make_array_storage(p, array, arr_size);
232 this->generate_input_error(p, array,
"Invalid type in CSV-included part of IST. Expected is Array!\n",
false);
241 if ( check_and_read_position_index(p, pos) ) {
243 include_data.
data_type = IncludeDataTypes::type_sel;
245 include_data.
type = selection;
246 if (csv_columns_map_.find(pos)!=csv_columns_map_.end()) {
247 THROW( ExcMultipleDefinitionCsvColumn() << EI_ColumnIndex(pos) << EI_ErrorAddress(p.
as_string()) );
249 csv_columns_map_[pos] = include_data;
254 string item_name = read_string_value(p, selection);
258 }
catch (Type::Selection::ExcSelectionKeyNotFound &exc) {
259 this->generate_input_error(p, selection,
"Wrong value '" + item_name +
"' of the Selection.",
false);
268 if ( check_and_read_position_index(p, pos) ) {
270 include_data.
data_type = IncludeDataTypes::type_bool;
273 if (csv_columns_map_.find(pos)!=csv_columns_map_.end()) {
274 THROW( ExcMultipleDefinitionCsvColumn() << EI_ColumnIndex(pos) << EI_ErrorAddress(p.
as_string()) );
276 csv_columns_map_[pos] = include_data;
281 return new StorageInt( read_bool_value(p, bool_type) );
288 if ( check_and_read_position_index(p, pos) ) {
290 include_data.
data_type = IncludeDataTypes::type_int;
293 if (csv_columns_map_.find(pos)!=csv_columns_map_.end()) {
294 THROW( ExcMultipleDefinitionCsvColumn() << EI_ColumnIndex(pos) << EI_ErrorAddress(p.
as_string()) );
296 csv_columns_map_[pos] = include_data;
301 return new StorageInt( read_int_value(p, int_type) );
308 if ( check_and_read_position_index(p, pos) ) {
310 include_data.
data_type = IncludeDataTypes::type_double;
312 include_data.
type = double_type;
313 if (csv_columns_map_.find(pos)!=csv_columns_map_.end()) {
314 THROW( ExcMultipleDefinitionCsvColumn() << EI_ColumnIndex(pos) << EI_ErrorAddress(p.
as_string()) );
316 csv_columns_map_[pos] = include_data;
321 return new StorageDouble( read_double_value(p, double_type) );
328 if ( check_and_read_position_index(p, pos) ) {
330 include_data.
data_type = IncludeDataTypes::type_string;
332 include_data.
type = string_type;
333 if (csv_columns_map_.find(pos)!=csv_columns_map_.end()) {
334 THROW( ExcMultipleDefinitionCsvColumn() << EI_ColumnIndex(pos) << EI_ErrorAddress(p.
as_string()) );
336 csv_columns_map_[pos] = include_data;
341 return new StorageString( read_string_value(p, string_type) );
348 for (
unsigned int i_source=csv_subtree_depth_, i_target=0; i_source<p.
path_.size(); ++i_source, ++i_target ) {
350 csv_storage_indexes[i_target] = p.
path_[i_source].first;
352 return csv_storage_indexes;
358 ASSERT(it!=csv_columns_map_.end()).error();
362 for (i=0; i<it->second.storage_indexes.size()-1; ++i) loop_storage = loop_storage->
get_item( it->second.storage_indexes[i] );
363 loop_storage->
set_item( it->second.storage_indexes[i], new_storage );
371 }
catch (ExcInputError &) {
377 if ( value.size() && (value.substr(0,1) ==
"$") ) {
379 pos = std::stoi( value.substr(1) );
381 }
catch (std::invalid_argument &) {
#define ASSERT_GE(a, b)
Definition of comparative assert macro (Greater or Equal)
#define ASSERT(expr)
Allow use shorter versions of macro names if these names is not used with external library...
static constexpr bool value
Dedicated class for storing path to input and output files.
#define WarningOut()
Macro defining 'warning' record of log.
#define ASSERT_PTR_DBG(ptr)
Definition of assert macro checking non-null pointer (PTR) only for debug mode.
#define THROW(whole_exception_expr)
Wrapper for throw. Saves the throwing point.