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'!",
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");
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;
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;
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) only for debug mode.
#define ASSERT_PTR(ptr)
Definition of assert macro checking non-null pointer (PTR) only for debug mode.
Dedicated class for storing path to input and output files.
#define THROW(whole_exception_expr)
Wrapper for throw. Saves the throwing point.
static constexpr bool value
#define WarningOut()
Macro defining 'warning' record of log.