Flow123d  last_with_con_2.0.0-663-gd0e2296
reader_to_storage.cc
Go to the documentation of this file.
1 /*!
2  *
3  * Copyright (C) 2015 Technical University of Liberec. All rights reserved.
4  *
5  * This program is free software; you can redistribute it and/or modify it under
6  * the terms of the GNU General Public License version 3 as published by the
7  * Free Software Foundation. (http://www.gnu.org/licenses/gpl-3.0.en.html)
8  *
9  * This program is distributed in the hope that it will be useful, but WITHOUT
10  * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS
11  * FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details.
12  *
13  *
14  * @file reader_to_storage.cc
15  * @brief
16  */
17 
18 #include <cstdint>
19 #include <limits>
20 #include <boost/iostreams/device/file.hpp>
21 #include <boost/iostreams/filtering_stream.hpp>
22 
23 #include "reader_to_storage.hh"
24 #include "input/path_json.hh"
25 #include "input/path_yaml.hh"
26 #include "input/input_type.hh"
27 #include "input/accessors.hh"
28 
29 
30 namespace Input {
31 using namespace std;
32 using namespace internal;
33 
34 
35 
36 /********************************************
37  * Implementation of public part of ReaderToStorage
38  */
39 
41 : storage_(nullptr),
42  root_type_(nullptr),
43  try_transpose_read_(false),
44  transpose_index_(0)
45 {}
46 
47 
48 
51 {
52  std::string fname = in_file;
53  std::string extension = fname.substr(fname.find_last_of(".") + 1);
55  if (extension == "con") {
56  format = FileFormat::format_JSON;
57  } else if (extension == "yaml") {
58  format = FileFormat::format_YAML;
59  } else {
60  THROW(ExcInputMessage() << EI_Message("Invalid extension of file " + fname + ".\nMust be 'con' or 'yaml'."));
61  }
62 
63  std::ifstream in;
64  in_file.open_stream(in);
65 
66  // finish of root_type ensures finish of whole IST
67  root_type.finish();
68 
69  read_stream(in, root_type, format);
70 }
71 
72 
73 
76 {
77  // finish of root_type ensures finish of whole IST
78  root_type.finish();
79 
80  try {
81  istringstream is(str);
82  read_stream(is, root_type, format);
83  } catch (ExcNotJSONFormat &e) {
84  e << EI_File("STRING: "+str); throw;
85  }
86 }
87 
88 
89 
90 void ReaderToStorage::read_stream(istream &in, const Type::TypeBase &root_type, FileFormat format)
91 {
92  ASSERT(storage_==nullptr).error();
93 
94  PathBase * root_path;
95  if (format == FileFormat::format_JSON) {
96  root_path = new PathJSON(in);
97  } else {
98  root_path = new PathYAML(in);
99  }
100 
101  // guarantee to delete root_path on function return even on exception
102  std::unique_ptr<PathBase> root_path_ptr(root_path);
103 
104  root_type_ = &root_type;
105  try {
106  storage_ = make_storage(*root_path_ptr, root_type_);
107  } catch (ExcInputError &e) {
108  if (format == FileFormat::format_JSON) {
109  e << EI_Format("JSON");
110  } else {
111  e << EI_Format("YAML");
112  }
113  throw;
114  }
115 
116  ASSERT_PTR(storage_).error();
117 }
118 
119 
120 
121 
122 
123 
124 /********************************************
125  * Implementation of private part of ReaderToStorage - make_storage dispatch
126  */
127 
128 
130 {
131  ASSERT_PTR(type).error("Can not dispatch, NULL pointer to TypeBase.");
132 
133  // find reference node, if doesn't exist return NULL
134  PathBase * ref_path = p.find_ref_node();
135  if (ref_path) {
136  // todo: mark passed references and check cyclic references
137 
138  // dereference and take data from there
139  StorageBase * storage = make_storage( *ref_path, type );
140  delete ref_path;
141  return storage;
142  }
143 
144  // dispatch types - complex types
145  if (typeid(*type) == typeid(Type::Tuple)) {
146  return make_storage(p, static_cast<const Type::Tuple *>(type) );
147  } else
148  if (typeid(*type) == typeid(Type::Record)) {
149  return make_storage(p, static_cast<const Type::Record *>(type) );
150  } else
151  if (typeid(*type) == typeid(Type::Array)) {
152  return make_storage(p, static_cast<const Type::Array *>(type) );
153  } else {
154  const Type::Abstract * abstract_record_type = dynamic_cast<const Type::Abstract *>(type);
155  if (abstract_record_type != NULL ) return make_storage(p, abstract_record_type );
156  }
157 
158  // return Null storage if there is null on the current location
159  if (p.is_null_type()) {
160  return new StorageNull();
161  }
162 
163  // dispatch types - scalar types
164  if (typeid(*type) == typeid(Type::Integer)) {
165  return make_storage(p, static_cast<const Type::Integer *>(type) );
166  } else
167  if (typeid(*type) == typeid(Type::Double)) {
168  return make_storage(p, static_cast<const Type::Double *>(type) );
169  } else
170  if (typeid(*type) == typeid(Type::Bool)) {
171  return make_storage(p, static_cast<const Type::Bool *>(type) );
172  } else
173  if (typeid(*type) == typeid(Type::Selection)) {
174  return make_storage(p, static_cast<const Type::Selection *>(type) );
175  } else {
176  const Type::String * string_type = dynamic_cast<const Type::String *>(type);
177  if (string_type != NULL ) return make_storage(p, string_type );
178 
179  // default -> error
180  THROW( Type::ExcUnknownDescendant() << Type::EI_TypeName(typeid(type).name()) );
181  }
182 
183  return new StorageNull();
184 }
185 
186 
188 {
189  // control test, check correct tag (or TYPE key) if Record is derived from Abstract
190  string record_name_from_tag = p.get_record_name();
191  if ( record_name_from_tag != "" ) {
192  ASSERT(record_name_from_tag == record->type_name())(record_name_from_tag)(record->type_name()).error("Inconsistent tag of record.");
193  }
194  std::set<string> keys_to_process;
195  bool effectively_null = p.is_effectively_null();
196  if ( p.get_record_key_set(keys_to_process) || effectively_null ) {
197  std::set<string>::iterator set_it;
198 
199  /*Type::Record::KeyIter key_it;
200  if ( record->has_key_iterator("TYPE", key_it) && record->auto_conversion_key_iter() != record->end() ) {
201  PathBase *type_path = p->clone();
202  if ( type_path.down( "TYPE" ) ) {
203  try {
204  ASSERT( type_path.get_string_value() == record->type_name() )(type_path.get_string_value())(record->type_name())
205  .error("Invalid value of TYPE key of record");
206  make_storage(type_path, key_it->type_.get() )->get_int();
207  } catch(Type::Selection::ExcSelectionKeyNotFound &e) {
208  return record_automatic_conversion(p, record);
209  }
210  }
211  else { // automatic conversion
212  return record_automatic_conversion(p, record);
213  }
214  }*/
215 
216  StorageArray *storage_array = new StorageArray(record->size());
217  // check individual keys
218  for( Type::Record::KeyIter it= record->begin(); it != record->end(); ++it) {
219  // remove processed key from keys_to_process
220  set_it = keys_to_process.find(it->key_);
221  if (set_it != keys_to_process.end()) {
222  keys_to_process.erase(set_it);
223  }
224 
225  if ( !effectively_null && p.down(it->key_) ) {
226  // key on input => check & use it
227  // check for obsolete key
228 
229  auto obsolete_it = it->attributes.find( Type::Attribute::obsolete() );
230  if ( obsolete_it != it->attributes.end()) {
231  WarningOut() << "Usage of the obsolete key: '" << it->key_ << "'\n" << obsolete_it -> second;
232  }
233 
234  StorageBase *storage = make_storage(p, it->type_.get());
235  if ( (typeid(*storage) == typeid(StorageNull)) && it->default_.has_value_at_declaration() ) {
236  delete storage;
237  storage = make_storage_from_default( it->default_.value(), it->type_ );
238  }
239  storage_array->new_item( it->key_index, storage );
240  p.up();
241  } else {
242  // key not on input
243  if (it->default_.is_obligatory() ) {
244  THROW( ExcInputError() << EI_Specification("Missing obligatory key '"+ it->key_ +"'.")
245  << EI_ErrorAddress(p.as_string()) << EI_InputType(record->desc()) );
246  } else if (it->default_.has_value_at_declaration() ) {
247  storage_array->new_item(it->key_index,
248  make_storage_from_default( it->default_.value(), it->type_ ) );
249  } else { // defalut - optional or default at read time
250  // set null
251  storage_array->new_item(it->key_index, new StorageNull() );
252  }
253  }
254  }
255 
256  for( set_it = keys_to_process.begin(); set_it != keys_to_process.end(); ++set_it) {
257  WarningOut() << "Unprocessed key '" << (*set_it) << "' in " << record->class_name()
258  << " '" << p.as_string() << "'." << std::endl;
259  }
260 
261  return storage_array;
262 
263  } else { // automatic conversion
264  return record_automatic_conversion(p, record);
265  }
266  // possibly construction of reduced record
267 }
268 
269 
271 {
272  Type::Record::KeyIter auto_key_it = record->auto_conversion_key_iter();
273  if ( auto_key_it != record->end() ) {
274  try {
275  StorageArray *storage_array = new StorageArray(record->size());
276  for( Type::Record::KeyIter it= record->begin(); it != record->end(); ++it) {
277  if ( it == auto_key_it ) {
278  // one key is initialized by input
279  storage_array->new_item(it->key_index, make_storage(p, it->type_.get()) );
280  } else if (it->default_.has_value_at_declaration() ) {
281  // other key from default values
282  storage_array->new_item(it->key_index,
283  make_storage_from_default( it->default_.value(), it->type_ ) );
284  } else { // defalut - optional or default at read time
285  ASSERT(! it->default_.is_obligatory())(it->key_).error("Obligatory key in auto-convertible Record.");
286  // set null
287  storage_array->new_item(it->key_index, new StorageNull() );
288  }
289  }
290 
291  return storage_array;
292  } catch (ExcInputError &e ) {
293  THROW( ExcAutomaticConversionError() << EI_RecordName(record->type_name()) << EI_InputErrorMessage(e.what()) );
294  }
295 
296  } else {
297  THROW( ExcInputError() << EI_Specification("The value should be '" + p.get_node_type(ValueTypes::obj_type) + "', but we found: ")
298  << EI_ErrorAddress(p.as_string()) << EI_JSON_Type( p.get_node_type(p.get_node_type_index()) )
299  << EI_InputType( record->desc()) );
300  }
301 
302  return NULL;
303 }
304 
305 
306 
308 {
309  string record_name = p.get_record_name();
310  if ( record_name == "" ) {
311  if ( ! abstr_rec->get_selection_default().has_value_at_declaration() ) {
312  THROW( ExcInputError() << EI_Specification("Can not determine type of the Abstract.") << EI_ErrorAddress(p.as_string())
313  << EI_JSON_Type( p.get_node_type(p.get_node_type_index()) ) << EI_InputType(abstr_rec->desc()) );
314  } else { // auto conversion
315  return abstract_automatic_conversion(p, abstr_rec);
316  }
317  } else {
318  try {
319  return make_storage(p, &( abstr_rec->get_descendant(record_name) ) );
320  } catch (Type::Selection::ExcSelectionKeyNotFound &exc) {
321  THROW( ExcInputError() << EI_Specification("Wrong value '" + record_name + "' of the Selection.")
322  << EI_ErrorAddress(p.as_string()) << EI_JSON_Type( "" ) << EI_InputType(abstr_rec->get_type_selection().desc()) );
323  }
324  }
325 
326  return NULL;
327 }
328 
329 
330 
332 {
333  // perform automatic conversion
334  const Type::Record *default_child = abstr_rec->get_default_descendant();
335  if (! default_child) THROW(ExcInputError()
336  << EI_Specification("Auto conversion of Abstract not allowed.\n")
337  << EI_ErrorAddress(p.as_string())
338  << EI_InputType(abstr_rec->desc())
339  );
340  return make_storage(p, default_child );
341 }
342 
343 
345 {
346  int arr_size;
347  if ( (arr_size = p.get_array_size()) != -1 ) {
348  if ( array->match_size( arr_size ) ) {
349  // copy the array and check type of values
350  StorageArray *storage_array = new StorageArray(arr_size);
351  for( int idx=0; idx < arr_size; idx++) {
352  p.down(idx);
353  const Type::TypeBase &sub_type = array->get_sub_type();
354  storage_array->new_item(idx, make_storage(p, &sub_type) );
355  p.up();
356  }
357  return storage_array;
358 
359  } else {
360  stringstream ss;
361  ss << arr_size;
362  THROW( ExcInputError()
363  << EI_Specification("Do not fit the size " + ss.str() + " of the Array.")
364  << EI_ErrorAddress(p.as_string()) << EI_InputType(array->desc()) );
365  }
366  } else {
367  // if transposition is carried, only conversion to array with one element is allowed
368  if (try_transpose_read_) {
369  // try automatic conversion to array with one element
370  const Type::TypeBase &sub_type = array->get_sub_type();
371  StorageBase *one_element_storage = make_storage(p, &sub_type);
372  return make_autoconversion_array_storage(p, array, one_element_storage);
373  } else {
374  // set variables managed transposition
375  try_transpose_read_ = true;
376  transpose_index_ = 0;
377  transpose_array_sizes_.clear();
378 
379  const Type::TypeBase &sub_type = array->get_sub_type();
380  StorageBase *first_item_storage;
381  try {
382  first_item_storage = make_storage(p, &sub_type);
383  } catch (ExcInputError &e) {
384  if ( !array->match_size(1) ) {
385  e << EI_Specification("The value should be '" + p.get_node_type(ValueTypes::array_type) + "', but we found: ");
386  }
387  e << EI_TransposeIndex(transpose_index_);
388  e << EI_TransposeAddress(p.as_string());
389  throw;
390  }
391 
392  // automatic conversion to array with one element
393  if (transpose_array_sizes_.size() == 0) {
394  try_transpose_read_ = false;
395  return make_autoconversion_array_storage(p, array, first_item_storage);
396  } else {
397 
398  // check sizes of arrays stored in transpose_array_sizes_
400  transpose_array_sizes_.end() );
401  if (transpose_array_sizes_.size() == 1) {
402  unsigned int sizes = transpose_array_sizes_[0]; // sizes of transposed
403 
404  // array size out of bounds
405  if ( !array->match_size( sizes ) ) {
406  stringstream ss;
407  ss << sizes;
408  THROW( ExcInputError() << EI_Specification("Result of transpose auto-conversion do not fit the size " + ss.str() + " of the Array.")
409  << EI_ErrorAddress(p.as_string()) << EI_InputType(array->desc()) );
410  }
411 
412  // create storage of array
413  StorageArray *storage_array = new StorageArray(sizes);
414  storage_array->new_item(0, first_item_storage);
415  if (sizes>1) {
417  while (transpose_index_ < sizes) {
418  try {
419  storage_array->new_item(transpose_index_, make_storage(p, &sub_type));
420  } catch (ExcInputError &e) {
421  e << EI_TransposeIndex(transpose_index_);
422  e << EI_TransposeAddress(p.as_string());
423  throw;
424  }
426  }
427  }
428 
429  try_transpose_read_ = false;
430  return storage_array;
431  } else {
432  THROW( ExcInputError()
433  << EI_Specification("Unequal sizes of sub-arrays during transpose auto-conversion of '" + p.get_node_type(ValueTypes::array_type) + "'")
434  << EI_ErrorAddress(p.as_string()) << EI_InputType(array->desc()) );
435  }
436  }
437  }
438 
439  }
440 
441  return NULL;
442 }
443 
444 
445 
447 {
448  int arr_size;
449  if ( (arr_size = p.get_array_size()) != -1 ) {
450 
451  StorageArray *storage_array = new StorageArray(tuple->size());
452  // check individual keys
453  for ( Type::Record::KeyIter it= tuple->begin(); it != tuple->end(); ++it) {
454  if ( p.down(it->key_index) ) {
455  // key on input => check & use it
456  StorageBase *storage = make_storage(p, it->type_.get());
457  if ( (typeid(*storage) == typeid(StorageNull)) && it->default_.has_value_at_declaration() ) {
458  delete storage;
459  storage = make_storage_from_default( it->default_.value(), it->type_ );
460  }
461  storage_array->new_item( it->key_index, storage );
462  p.up();
463  } else {
464  // key not on input
465  if (it->default_.is_obligatory() ) {
466  stringstream ss;
467  ss << tuple->obligatory_keys_count();
468  THROW( ExcInputError()
469  << EI_Specification("Too small size of '" + p.get_node_type(ValueTypes::array_type) + "' defining Tuple with "
470  + ss.str() + " obligatory keys.")
471  << EI_ErrorAddress(p.as_string())
472  << EI_InputType(tuple->desc()) );
473  } else if (it->default_.has_value_at_declaration() ) {
474  storage_array->new_item(it->key_index,
475  make_storage_from_default( it->default_.value(), it->type_ ) );
476  } else { // default - optional or default at read time
477  // set null
478  storage_array->new_item(it->key_index, new StorageNull() );
479  }
480  }
481  }
482 
483  if ( arr_size > (int)tuple->size() ) {
484  WarningOut().fmt("Unprocessed keys in tuple '{}', tuple has {} keys but the input is specified by {} values.\n",
485  p.as_string().c_str(), tuple->size(), arr_size );
486  }
487 
488  return storage_array;
489 
490  } else {
491  return make_storage(p, static_cast<const Type::Record *>(tuple) );
492  }
493 }
494 
495 
496 
498 {
499  if ( try_transpose_read_ && p.is_array_type() ) {
500  // transpose auto-conversion for array type
501  return this->make_transposed_storage(p, selection);
502  }
503  string item_name;
504  try {
505  item_name = p.get_string_value();
506  int value = selection->name_to_int( item_name );
507  return new StorageInt( value );
508  } catch (ExcInputError & e) {
509  e << EI_Specification("The value should be '" + p.get_node_type(ValueTypes::str_type) + "', but we found: ");
510  e << EI_ErrorAddress(p.as_string());
511  e << EI_JSON_Type( p.get_node_type(p.get_node_type_index()) );
512  e << EI_InputType(selection->desc());
513  throw;
514  } catch (Type::Selection::ExcSelectionKeyNotFound &exc) {
515  THROW( ExcInputError() << EI_Specification("Wrong value '" + item_name + "' of the Selection.")
516  << EI_ErrorAddress(p.as_string()) << EI_JSON_Type( "" ) << EI_InputType(selection->desc()) );
517  }
518 
519  return NULL;
520 }
521 
522 
523 
525 {
526  if ( try_transpose_read_ && p.is_array_type() ) {
527  // transpose auto-conversion for array type
528  return this->make_transposed_storage(p, bool_type);
529  }
530  try {
531  return new StorageBool( p.get_bool_value() );
532  }
533  catch (ExcInputError & e) {
534  e << EI_Specification("The value should be '" + p.get_node_type(ValueTypes::bool_type) + "', but we found: ");
535  e << EI_JSON_Type( p.get_node_type(p.get_node_type_index()) );
536  e << EI_ErrorAddress(p.as_string());
537  e << EI_InputType(bool_type->desc());
538  throw;
539  }
540  return NULL;
541 }
542 
543 
544 
546 {
547  if ( try_transpose_read_ && p.is_array_type() ) {
548  // transpose auto-conversion for array type
549  return this->make_transposed_storage(p, int_type);
550  }
551  std::int64_t value;
552  try {
553  value = p.get_int_value();
554  }
555  catch (ExcInputError & e) {
556  e << EI_Specification("The value should be '" + p.get_node_type(ValueTypes::int_type) + "', but we found: ");
557  e << EI_ErrorAddress(p.as_string());
558  e << EI_JSON_Type( p.get_node_type(p.get_node_type_index()) );
559  e << EI_InputType(int_type->desc());
560  throw;
561  }
562 
563  if ( int_type->match(value) )
564  {
565  return new StorageInt( value );
566  } else {
567  THROW( ExcInputError() << EI_Specification("Value out of bounds.") << EI_ErrorAddress(p.as_string())
568  << EI_InputType(int_type->desc()) );
569  }
570 
571  return NULL;
572 }
573 
574 
575 
577 {
578  if ( try_transpose_read_ && p.is_array_type() ) {
579  // transpose auto-conversion for array type
580  return this->make_transposed_storage(p, double_type);
581  }
582  double value;
583 
584  try {
585  value = p.get_double_value();
586  }
587  catch (ExcInputError & e) {
588  e << EI_Specification("The value should be '" + p.get_node_type(ValueTypes::real_type) + "', but we found: ");
589  e << EI_ErrorAddress(p.as_string());
590  e << EI_JSON_Type( p.get_node_type(p.get_node_type_index()) );
591  e << EI_InputType(double_type->desc());
592  throw;
593  }
594 
595  if (double_type->match(value)) {
596  return new StorageDouble( value );
597  } else {
598  THROW( ExcInputError() << EI_Specification("Value out of bounds.") << EI_ErrorAddress(p.as_string())
599  << EI_InputType(double_type->desc()) );
600  }
601 
602  return NULL;
603 }
604 
605 
606 
608 {
609  if ( try_transpose_read_ && p.is_array_type() ) {
610  // transpose auto-conversion for array type
611  return this->make_transposed_storage(p, string_type);
612  }
613  string value;
614  try {
615  value = p.get_string_value();
616  }
617  catch (ExcInputError & e) {
618  if (try_transpose_read_) {
619  return this->make_transposed_storage(p, string_type);
620  }
621  e << EI_Specification("The value should be '" + p.get_node_type(ValueTypes::str_type) + "', but we found: ");
622  e << EI_ErrorAddress(p.as_string());
623  e << EI_JSON_Type( p.get_node_type(p.get_node_type_index()) );
624  e << EI_InputType(string_type->desc());
625  throw;
626  }
627 
628  if (string_type->match(value))
629  return new StorageString( value );
630  else
631  THROW( ExcInputError() << EI_Specification("Output file can not be given by absolute path: '" + value + "'")
632  << EI_ErrorAddress(p.as_string()) << EI_JSON_Type("") << EI_InputType(string_type->desc()) );
633 
634  return NULL;
635 }
636 
637 
638 
639 StorageBase * ReaderToStorage::make_storage_from_default(const string &dflt_str, std::shared_ptr<Type::TypeBase> type) {
640  try {
641  // default strings must be valid JSON
642  Type::Default dflt(dflt_str);
643  return dflt.get_storage(type);
644 
645  } catch (Input::Type::ExcWrongDefault & e) {
646  // message to distinguish exceptions thrown during Default value check at declaration
647  e << Type::EI_Desc("Wrong default value while reading an input stream:\n");
648  e << EI_KeyName("UNKNOWN KEY");
649  throw;
650  } catch (Input::Type::ExcWrongDefaultJSON & e) {
651  e << EI_KeyName("UNKNOWN KEY");
652  throw;
653  }
654 
655  return NULL;
656 }
657 
658 
659 
661  ASSERT(try_transpose_read_).error();
662  ASSERT(p.is_array_type()).error();
663 
664  int arr_size = p.get_array_size();
665  if ( arr_size == 0 ) {
666  THROW( ExcInputError() << EI_Specification("Empty array during transpose auto-conversion.")
667  << EI_ErrorAddress(p.as_string()) << EI_InputType(type->desc()) );
668  } else {
669  if (transpose_index_ == 0) transpose_array_sizes_.push_back( arr_size );
671  StorageBase *storage = make_storage(p, type);
672  p.up();
673  return storage;
674  }
675 
676  return NULL;
677 }
678 
679 
680 
682 {
683  if ( array->match_size( 1 ) ) {
684  StorageArray *storage_array = new StorageArray(1);
685  storage_array->new_item(0, item);
686 
687  return storage_array;
688  } else {
689  THROW( ExcInputError()
690  << EI_Specification("During transpose auto-conversion, the conversion to the single element array not allowed. Require type: '" + p.get_node_type(ValueTypes::array_type) + "'\nFound on input: ")
691  << EI_ErrorAddress(p.as_string()) << EI_JSON_Type( p.get_node_type(p.get_node_type_index()) ) << EI_InputType(array->desc()) );
692  }
693 
694  return NULL;
695 }
696 
697 
698 
699 /********************************************88
700  * Implementation
701  */
702 
703 template <class T>
705 {
706  ASSERT_PTR(storage_).error();
707 
708  Address addr(storage_, root_type_);
709  // try to create an iterator just to check type
710  Iterator<T>( *root_type_, addr, 0);
711 
712  auto tmp_root_type = static_cast<const typename T::InputType &>(*root_type_);
713  return T( addr, tmp_root_type );
714 }
715 
716 
717 template ::Input::Record ReaderToStorage::get_root_interface<::Input::Record>() const;
718 template ::Input::Array ReaderToStorage::get_root_interface<::Input::Array>() const;
719 template ::Input::AbstractRecord ReaderToStorage::get_root_interface<::Input::AbstractRecord>() const;
720 template ::Input::Tuple ReaderToStorage::get_root_interface<::Input::Tuple>() const;
721 //template ReaderToStorage::get_root_interface<::Input::>()->::Input::AbstractRecord const;
722 
723 
724 } // namespace Input
bool try_transpose_read_
Flag signed that "expected" transposed part of input tree is processed.
const Record & get_descendant(const string &name) const
Returns reference to the inherited Record with given name.
void read_stream(istream &in, const Type::TypeBase &root_type, FileFormat format)
This method actually reads the given stream in.
Base of classes for declaring structure of the input data.
Definition: type_base.hh:93
Base class for nodes of a data storage tree.
Definition: storage.hh:68
unsigned int transpose_index_
Index of processed item in transposed part of input tree.
std::vector< struct Key >::const_iterator KeyIter
Public typedef of constant iterator into array of keys.
Definition: type_record.hh:206
FileFormat
Possible formats of input files.
Class used by ReaderToStorage class to iterate over the YAML tree provided by yaml-cpp library...
Definition: path_yaml.hh:39
vector< unsigned int > transpose_array_sizes_
Helper vector what allows check sizes of all transposed Arrays.
unsigned int size() const
Returns number of keys in the Record.
Definition: type_record.hh:588
Class used by ReaderToStorage class to iterate over the JSON tree provided by json_spirit library...
Definition: path_json.hh:40
string type_name() const override
Implements Type::TypeBase::type_name.
Definition: type_record.cc:315
virtual bool down(unsigned int index)=0
Dive one level down into path hierarchy.
string desc() const
Returns string with Type extensive documentation.
Definition: type_base.cc:75
Reader for (slightly) modified input files.
Class Input::Type::Default specifies default value of keys of a Input::Type::Record.
Definition: type_record.hh:50
virtual string class_name() const override
Override Type::TypeBase::class_name.
Definition: type_record.hh:338
Class for declaration of the input of type Bool.
Definition: type_base.hh:465
Base abstract class used by ReaderToStorage class to iterate over the input tree. ...
Definition: path_base.hh:39
int name_to_int(const string &key) const
Converts given value name key to the value.
std::string as_string() const
Returns string address of current position.
Definition: path_base.cc:48
std::string format(CStringRef format_str, ArgList args)
Definition: format.h:3141
virtual std::string get_record_name() const =0
Gets name of descendant Record of Abstract.
virtual bool get_record_key_set(std::set< std::string > &) const =0
Get set of keys of head type record, if head type is not record return false.
virtual bool is_effectively_null() const =0
Check empty Input Type Record, necessary for correct proccess of YAML output, for JSON has no effect...
StorageBase * make_storage(PathBase &p, const Type::TypeBase *type)
Create storage of given type.
virtual FinishStatus finish(FinishStatus finish_type=FinishStatus::regular_)
Finish method. Finalize construction of "Lazy types": Record, Selection, Abstract and generic type...
Definition: type_base.hh:206
virtual unsigned int get_node_type_index() const =0
Get index of head type, value corresponds with order in json_type_names vector.
#define ASSERT(expr)
Allow use shorter versions of macro names if these names is not used with external library...
Definition: asserts.hh:347
std::string get_node_type(unsigned int type_idx) const
Get short string description of node type, method is used for printout of messages.
Definition: path_base.cc:64
virtual int get_array_size() const =0
Get size of array (sequence type), if object is not array return -1.
const Type::TypeBase * root_type_
Root of the declaration tree of the data in the storage.
Class for declaration of the integral input data.
Definition: type_base.hh:496
KeyIter begin() const
Container-like access to the keys of the Record.
Definition: type_record.hh:565
Class for declaration of inputs sequences.
Definition: type_base.hh:348
virtual double get_double_value() const =0
Get double value of head node or throw exception.
static constexpr bool value
Definition: json.hpp:87
StorageBase * abstract_automatic_conversion(PathBase &p, const Type::Abstract *abstr_rec)
Apply automatic conversion of Type::Abstract type.
void open_stream(Stream &stream) const
Definition: file_path.cc:211
Class for declaration of the input data that are floating point numbers.
Definition: type_base.hh:549
bool match(std::int64_t value) const
Check valid value of Integer.
Definition: type_base.cc:350
T get_root_interface() const
Returns the root accessor.
Input::StorageBase * get_storage(std::shared_ptr< TypeBase > type) const
Return storage_, if storage_ is NULL, call check_validity method.
Definition: type_record.cc:86
bool match(double value) const
Returns true if the given integer value conforms to the Type::Double bounds.
Definition: type_base.cc:382
ReaderToStorage()
Default constructor.
virtual bool get_bool_value() const =0
Get boolean value of head node or throw exception.
Default & get_selection_default() const
StorageBase * make_transposed_storage(PathBase &p, const Type::TypeBase *type)
Apply transposition and create storage of Type::Array type.
bool match_size(unsigned int size) const
Checks size of particular array.
Definition: type_base.hh:414
StorageBase * make_autoconversion_array_storage(PathBase &p, const Type::Array *array, StorageBase *item)
Apply conversion to one element storage of Type::Array type.
const Record * get_default_descendant() const
Returns default descendant.
Class for declaration of polymorphic Record.
void new_item(unsigned int index, StorageBase *item)
Definition: storage.cc:101
const Selection & get_type_selection() const
Returns reference to Selection type of the implicit key TYPE.
bool has_value_at_declaration() const
Returns true if the default value is or will be available when someone tries to read the value...
Definition: type_record.hh:121
virtual bool is_array_type() const =0
Check if type of head node is array.
virtual std::string get_string_value() const =0
Get string value of head node or throw exception.
Dedicated class for storing path to input and output files.
Definition: file_path.hh:48
StorageBase * record_automatic_conversion(PathBase &p, const Type::Record *record)
Apply automatic conversion of Type::Record type.
virtual bool match(const string &value) const
Particular descendants can check validity of the string.
Definition: type_base.cc:463
Tuple type proxy class.
Definition: type_tuple.hh:41
virtual bool is_null_type() const =0
Check if type of head node is null.
StorageBase * make_storage_from_default(const string &dflt_str, std::shared_ptr< Type::TypeBase > type)
Dispatch according to type and create corresponding storage from the given string.
#define ASSERT_PTR(ptr)
Definition of assert macro checking non-null pointer (PTR)
Definition: asserts.hh:336
virtual std::int64_t get_int_value() const =0
Get integer value of head node or throw exception.
KeyIter end() const
Container-like access to the keys of the Record.
Definition: type_record.hh:573
const TypeBase & get_sub_type() const
Getter for the type of array items.
Definition: type_base.hh:410
#define WarningOut()
Macro defining &#39;warning&#39; record of log.
Definition: logger.hh:234
unsigned int obligatory_keys_count() const
Return count of obligatory keys.
Definition: type_tuple.cc:130
Record type proxy class.
Definition: type_record.hh:171
virtual PathBase * find_ref_node()=0
Check if current head node is containing one key REF of type string.
static string obsolete()
virtual void up()=0
Return one level up in the hierarchy.
Class for declaration of the input data that are in string format.
Definition: type_base.hh:599
#define THROW(whole_exception_expr)
Wrapper for throw. Saves the throwing point.
Definition: exceptions.hh:45
Template for classes storing finite set of named values.
KeyIter auto_conversion_key_iter() const
Returns iterator to auto-conversion key.
Definition: type_record.cc:327
StorageBase * storage_
Storage of the read and checked input data.