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);
211 if (unused_columns.size()) {
213 for (std::set<unsigned int>::iterator it=unused_columns.begin(); it!=unused_columns.end(); ++it)
215 WarningOut().fmt(
"Unused columns: {}\nin imported CSV input file: {}\n", ss.str(), tok.f_name());
217 return storage_array;
220 this->generate_input_error(p, array,
"Invalid definition of CSV include.",
false);
229 return this->make_array_storage(p, array, arr_size);
231 this->generate_input_error(p, array,
"Invalid type in CSV-included part of IST. Expected is Array!\n",
false);
240 if ( check_and_read_position_index(p, pos) ) {
242 include_data.
data_type = IncludeDataTypes::type_sel;
244 include_data.
type = selection;
245 if (csv_columns_map_.find(pos)!=csv_columns_map_.end()) {
246 THROW( ExcMultipleDefinitionCsvColumn() << EI_ColumnIndex(pos) << EI_ErrorAddress(p.
as_string()) );
248 csv_columns_map_[pos] = include_data;
253 string item_name = read_string_value(p, selection);
257 }
catch (Type::Selection::ExcSelectionKeyNotFound &exc) {
258 this->generate_input_error(p, selection,
"Wrong value '" + item_name +
"' of the Selection.",
false);
267 if ( check_and_read_position_index(p, pos) ) {
269 include_data.
data_type = IncludeDataTypes::type_bool;
272 if (csv_columns_map_.find(pos)!=csv_columns_map_.end()) {
273 THROW( ExcMultipleDefinitionCsvColumn() << EI_ColumnIndex(pos) << EI_ErrorAddress(p.
as_string()) );
275 csv_columns_map_[pos] = include_data;
280 return new StorageInt( read_bool_value(p, bool_type) );
287 if ( check_and_read_position_index(p, pos) ) {
289 include_data.
data_type = IncludeDataTypes::type_int;
292 if (csv_columns_map_.find(pos)!=csv_columns_map_.end()) {
293 THROW( ExcMultipleDefinitionCsvColumn() << EI_ColumnIndex(pos) << EI_ErrorAddress(p.
as_string()) );
295 csv_columns_map_[pos] = include_data;
300 return new StorageInt( read_int_value(p, int_type) );
307 if ( check_and_read_position_index(p, pos) ) {
309 include_data.
data_type = IncludeDataTypes::type_double;
311 include_data.
type = double_type;
312 if (csv_columns_map_.find(pos)!=csv_columns_map_.end()) {
313 THROW( ExcMultipleDefinitionCsvColumn() << EI_ColumnIndex(pos) << EI_ErrorAddress(p.
as_string()) );
315 csv_columns_map_[pos] = include_data;
320 return new StorageDouble( read_double_value(p, double_type) );
327 if ( check_and_read_position_index(p, pos) ) {
329 include_data.
data_type = IncludeDataTypes::type_string;
331 include_data.
type = string_type;
332 if (csv_columns_map_.find(pos)!=csv_columns_map_.end()) {
333 THROW( ExcMultipleDefinitionCsvColumn() << EI_ColumnIndex(pos) << EI_ErrorAddress(p.
as_string()) );
335 csv_columns_map_[pos] = include_data;
340 return new StorageString( read_string_value(p, string_type) );
347 for (
unsigned int i_source=csv_subtree_depth_, i_target=0; i_source<p.
path_.size(); ++i_source, ++i_target ) {
349 csv_storage_indexes[i_target] = p.
path_[i_source].first;
351 return csv_storage_indexes;
357 ASSERT(it!=csv_columns_map_.end()).error();
361 for (i=0; i<it->second.storage_indexes.size()-1; ++i) loop_storage = loop_storage->
get_item( it->second.storage_indexes[i] );
362 loop_storage->
set_item( it->second.storage_indexes[i], new_storage );
370 }
catch (ExcInputError &) {
376 if ( value.size() && (value.substr(0,1) ==
"$") ) {
378 pos = std::stoi( value.substr(1) );
380 }
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 THROW(whole_exception_expr)
Wrapper for throw. Saves the throwing point.