Flow123d  release_1.8.2-1603-g0109a2b
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/accessors.hh"
27 
28 namespace Input {
29 using namespace std;
30 using namespace internal;
31 
32 
33 
34 /********************************************
35  * Implementation of public part of ReaderToStorage
36  */
37 
39 : storage_(nullptr),
40  root_type_(nullptr),
41  try_transpose_read_(false)
42 {}
43 
44 
45 
46 ReaderToStorage::ReaderToStorage(const FilePath &in_file, const Type::TypeBase &root_type)
48 {
49  std::string fname = in_file;
50  std::string extension = fname.substr(fname.find_last_of(".") + 1);
51  FileFormat format;
52  if (extension == "con") {
53  format = FileFormat::format_JSON;
54  } else if (extension == "yaml") {
55  format = FileFormat::format_YAML;
56  } else {
57  THROW(ExcInputMessage() << EI_Message("Invalid extension of file " + fname + ".\nMust be 'con' or 'yaml'."));
58  }
59 
60  std::ifstream in(fname.c_str());
61  if (! in) {
62  THROW(ExcInputMessage() << EI_Message("Can not open main input file: '" + fname + "'.\n"));
63  }
64 
65  // finish all lazy input types
67 
68  read_stream(in, root_type, format);
69 }
70 
71 
72 
73 ReaderToStorage::ReaderToStorage( const string &str, const Type::TypeBase &root_type, FileFormat format)
75 {
76  // finish all lazy input types
78 
79  try {
80  istringstream is(str);
81  read_stream(is, root_type, format);
82  } catch (ExcNotJSONFormat &e) {
83  e << EI_File("STRING: "+str); throw;
84  }
85 }
86 
87 
88 
89 void ReaderToStorage::read_stream(istream &in, const Type::TypeBase &root_type, FileFormat format)
90 {
91  FEAL_DEBUG_ASSERT(storage_==nullptr).error();
92 
93  PathBase * root_path;
94  if (format == FileFormat::format_JSON) {
95  root_path = new PathJSON(in);
96  } else {
97  root_path = new PathYAML(in);
98  }
99 
100  // guarantee to delete root_path on function return even on exception
101  std::unique_ptr<PathBase> root_path_ptr(root_path);
102 
103  root_type_ = &root_type;
104  try {
105  storage_ = make_storage(*root_path_ptr, root_type_);
106  } catch (ExcInputError &e) {
107  if (format == FileFormat::format_JSON) {
108  e << EI_Format("JSON");
109  } else {
110  e << EI_Format("YAML");
111  }
112  throw;
113  }
114 
115  FEAL_DEBUG_ASSERT(storage_ != nullptr).error();
116 }
117 
118 
119 
120 
121 
122 
123 /********************************************
124  * Implementation of private part of ReaderToStorage - make_storage dispatch
125  */
126 
127 
129 {
130  FEAL_DEBUG_ASSERT(type != NULL).error("Can not dispatch, NULL pointer to TypeBase.");
131 
132  // find reference node, if doesn't exist return NULL
133  PathBase * ref_path = p.find_ref_node();
134  if (ref_path) {
135  // todo: mark passed references and check cyclic references
136 
137  // dereference and take data from there
138  StorageBase * storage = make_storage( *ref_path, type );
139  delete ref_path;
140  return storage;
141  }
142 
143  // return Null storage if there is null on the current location
144  if (p.is_null_type())
145  return new StorageNull();
146 
147  // dispatch types
148  if (typeid(*type) == typeid(Type::Tuple)) {
149  return make_storage(p, static_cast<const Type::Tuple *>(type) );
150  } else
151  if (typeid(*type) == typeid(Type::Record)) {
152  return make_storage(p, static_cast<const Type::Record *>(type) );
153  } else
154  if (typeid(*type) == typeid(Type::Array)) {
155  return make_storage(p, static_cast<const Type::Array *>(type) );
156  } else
157  if (typeid(*type) == typeid(Type::Integer)) {
158  return make_storage(p, static_cast<const Type::Integer *>(type) );
159  } else
160  if (typeid(*type) == typeid(Type::Double)) {
161  return make_storage(p, static_cast<const Type::Double *>(type) );
162  } else
163  if (typeid(*type) == typeid(Type::Bool)) {
164  return make_storage(p, static_cast<const Type::Bool *>(type) );
165  } else
166  if (typeid(*type) == typeid(Type::Selection)) {
167  return make_storage(p, static_cast<const Type::Selection *>(type) );
168  } else {
169  const Type::Abstract * abstract_record_type = dynamic_cast<const Type::Abstract *>(type);
170  if (abstract_record_type != NULL ) return make_storage(p, abstract_record_type );
171 
172  const Type::String * string_type = dynamic_cast<const Type::String *>(type);
173  if (string_type != NULL ) return make_storage(p, string_type );
174 
175  // default -> error
176  xprintf(Err,"Unknown descendant of TypeBase class, name: %s\n", typeid(type).name());
177  }
178 
179  return new StorageNull();
180 }
181 
182 
184 {
185  std::set<string> keys_to_process;
186  if ( p.get_record_key_set(keys_to_process) ) {
187  std::set<string>::iterator set_it;
188 
189  /*Type::Record::KeyIter key_it;
190  if ( record->has_key_iterator("TYPE", key_it) && record->auto_conversion_key_iter() != record->end() ) {
191  PathBase *type_path = p->clone();
192  if ( type_path.down( "TYPE" ) ) {
193  try {
194  FEAL_ASSERT( type_path.get_string_value() == record->type_name() )(type_path.get_string_value())(record->type_name())
195  .error("Invalid value of TYPE key of record");
196  make_storage(type_path, key_it->type_.get() )->get_int();
197  } catch(Type::Selection::ExcSelectionKeyNotFound &e) {
198  return record_automatic_conversion(p, record);
199  }
200  }
201  else { // automatic conversion
202  return record_automatic_conversion(p, record);
203  }
204  }*/
205 
206  StorageArray *storage_array = new StorageArray(record->size());
207  // check individual keys
208  for( Type::Record::KeyIter it= record->begin(); it != record->end(); ++it) {
209  // remove processed key from keys_to_process
210  set_it = keys_to_process.find(it->key_);
211  if (set_it != keys_to_process.end()) {
212  keys_to_process.erase(set_it);
213  }
214 
215  if ( p.down(it->key_) ) {
216  // key on input => check & use it
217  StorageBase *storage = make_storage(p, it->type_.get());
218  if ( (typeid(*storage) == typeid(StorageNull)) && it->default_.has_value_at_declaration() ) {
219  delete storage;
220  storage = make_storage_from_default( it->default_.value(), it->type_ );
221  }
222  storage_array->new_item( it->key_index, storage );
223  p.up();
224  } else {
225  // key not on input
226  if (it->default_.is_obligatory() ) {
227  THROW( ExcInputError() << EI_Specification("Missing obligatory key '"+ it->key_ +"'.")
228  << EI_ErrorAddress(p.as_string()) << EI_InputType(record->desc()) );
229  } else if (it->default_.has_value_at_declaration() ) {
230  storage_array->new_item(it->key_index,
231  make_storage_from_default( it->default_.value(), it->type_ ) );
232  } else { // defalut - optional or default at read time
233  // set null
234  storage_array->new_item(it->key_index, new StorageNull() );
235  }
236  }
237  }
238 
239  for( set_it = keys_to_process.begin(); set_it != keys_to_process.end(); ++set_it) {
240  xprintf(Warn, "Unprocessed key '%s' in %s '%s'.\n", (*set_it).c_str(), record->class_name().c_str(), p.as_string().c_str() );
241  }
242 
243  return storage_array;
244 
245  } else { // automatic conversion
246  return record_automatic_conversion(p, record);
247  }
248  // possibly construction of reduced record
249 }
250 
251 
253 {
254  Type::Record::KeyIter auto_key_it = record->auto_conversion_key_iter();
255  if ( auto_key_it != record->end() ) {
256  try {
257  StorageArray *storage_array = new StorageArray(record->size());
258  for( Type::Record::KeyIter it= record->begin(); it != record->end(); ++it) {
259  if ( it == auto_key_it ) {
260  // one key is initialized by input
261  storage_array->new_item(it->key_index, make_storage(p, it->type_.get()) );
262  } else if (it->default_.has_value_at_declaration() ) {
263  // other key from default values
264  storage_array->new_item(it->key_index,
265  make_storage_from_default( it->default_.value(), it->type_ ) );
266  } else { // defalut - optional or default at read time
267  FEAL_DEBUG_ASSERT(! it->default_.is_obligatory())(it->key_).error("Obligatory key in auto-convertible Record.");
268  // set null
269  storage_array->new_item(it->key_index, new StorageNull() );
270  }
271  }
272 
273  return storage_array;
274  } catch (ExcInputError &e ) {
275  THROW( ExcAutomaticConversionError() << EI_RecordName(record->type_name()) << EI_InputErrorMessage(e.what()) );
276  }
277 
278  } else {
279  THROW( ExcInputError() << EI_Specification("The value should be '" + p.get_node_type(ValueTypes::obj_type) + "', but we found: ")
280  << EI_ErrorAddress(p.as_string()) << EI_JSON_Type( p.get_node_type(p.get_node_type_index()) )
281  << EI_InputType( record->desc()) );
282  }
283 
284  return NULL;
285 }
286 
287 
288 
290 {
291  if ( p.is_record_type() ) {
292 
293  string descendant_name = p.get_descendant_name();
294  if ( descendant_name == "" ) {
295  if ( ! abstr_rec->get_selection_default().has_value_at_declaration() ) {
296  THROW( ExcInputError() << EI_Specification("Missing key 'TYPE' in Abstract.") << EI_ErrorAddress(p.as_string()) << EI_InputType(abstr_rec->desc()) );
297  } else { // auto conversion
298  return abstract_automatic_conversion(p, abstr_rec);
299  }
300  } else {
301  try {
302  return make_storage(p, &( abstr_rec->get_descendant(descendant_name) ) );
303  } catch (Type::Selection::ExcSelectionKeyNotFound &exc) {
304  THROW( ExcInputError() << EI_Specification("Wrong value '" + descendant_name + "' of the Selection.")
305  << EI_ErrorAddress(p.as_string()) << EI_JSON_Type( "" ) << EI_InputType(abstr_rec->get_type_selection().desc()) );
306  }
307  }
308  } else {
309  if ( ! abstr_rec->get_selection_default().has_value_at_declaration() ) {
310  THROW( ExcInputError() << EI_Specification("The value should be '" + p.get_node_type(ValueTypes::obj_type) + "', but we found: ")
311  << EI_ErrorAddress(p.as_string()) << EI_JSON_Type( p.get_node_type(p.get_node_type_index()) ) << EI_InputType(abstr_rec->desc()) );
312  } else { // auto conversion
313  return abstract_automatic_conversion(p, abstr_rec);
314  }
315  }
316 
317  return NULL;
318 }
319 
320 
321 
323 {
324  // perform automatic conversion
325  const Type::Record *default_child = abstr_rec->get_default_descendant();
326  if (! default_child) THROW(ExcInputError()
327  << EI_Specification("Auto conversion of Abstract not allowed.\n")
328  << EI_ErrorAddress(p.as_string())
329  << EI_InputType(abstr_rec->desc())
330  );
331  return make_storage(p, default_child );
332 }
333 
334 
336 {
337  int arr_size;
338  if ( (arr_size = p.get_array_size()) != -1 ) {
339  if ( array->match_size( arr_size ) ) {
340  // copy the array and check type of values
341  StorageArray *storage_array = new StorageArray(arr_size);
342  for( int idx=0; idx < arr_size; idx++) {
343  p.down(idx);
344  const Type::TypeBase &sub_type = array->get_sub_type();
345  storage_array->new_item(idx, make_storage(p, &sub_type) );
346  p.up();
347  }
348  return storage_array;
349 
350  } else {
351  stringstream ss;
352  ss << arr_size;
353  THROW( ExcInputError()
354  << EI_Specification("Do not fit the size " + ss.str() + " of the Array.")
355  << EI_ErrorAddress(p.as_string()) << EI_InputType(array->desc()) );
356  }
357  } else {
358  // if transposition is carried, only conversion to array with one element is allowed
359  if (try_transpose_read_) {
360  // try automatic conversion to array with one element
361  const Type::TypeBase &sub_type = array->get_sub_type();
362  StorageBase *one_element_storage = make_storage(p, &sub_type);
363  return make_autoconversion_array_storage(p, array, one_element_storage);
364  } else {
365  // set variables managed transposition
366  try_transpose_read_ = true;
367  transpose_index_ = 0;
368  transpose_array_sizes_.clear();
369 
370  const Type::TypeBase &sub_type = array->get_sub_type();
371  StorageBase *first_item_storage;
372  try {
373  first_item_storage = make_storage(p, &sub_type);
374  } catch (ExcInputError &e) {
375  if ( !array->match_size(1) ) {
376  e << EI_Specification("The value should be '" + p.get_node_type(ValueTypes::array_type) + "', but we found: ");
377  }
378  e << EI_TransposeIndex(transpose_index_);
379  e << EI_TransposeAddress(p.as_string());
380  throw;
381  }
382 
383  // automatic conversion to array with one element
384  if (transpose_array_sizes_.size() == 0) {
385  try_transpose_read_ = false;
386  return make_autoconversion_array_storage(p, array, first_item_storage);
387  } else {
388 
389  // check sizes of arrays stored in transpose_array_sizes_
391  transpose_array_sizes_.end() );
392  if (transpose_array_sizes_.size() == 1) {
393  unsigned int sizes = transpose_array_sizes_[0]; // sizes of transposed
394 
395  // array size out of bounds
396  if ( !array->match_size( sizes ) ) {
397  stringstream ss;
398  ss << sizes;
399  THROW( ExcInputError() << EI_Specification("Result of transpose auto-conversion do not fit the size " + ss.str() + " of the Array.")
400  << EI_ErrorAddress(p.as_string()) << EI_InputType(array->desc()) );
401  }
402 
403  // create storage of array
404  StorageArray *storage_array = new StorageArray(sizes);
405  storage_array->new_item(0, first_item_storage);
406  if (sizes>1) {
408  while (transpose_index_ < sizes) {
409  try {
410  storage_array->new_item(transpose_index_, make_storage(p, &sub_type));
411  } catch (ExcInputError &e) {
412  e << EI_TransposeIndex(transpose_index_);
413  e << EI_TransposeAddress(p.as_string());
414  throw;
415  }
417  }
418  }
419 
420  try_transpose_read_ = false;
421  return storage_array;
422  } else {
423  THROW( ExcInputError()
424  << EI_Specification("Unequal sizes of sub-arrays during transpose auto-conversion of '" + p.get_node_type(ValueTypes::array_type) + "'")
425  << EI_ErrorAddress(p.as_string()) << EI_InputType(array->desc()) );
426  }
427  }
428  }
429 
430  }
431 
432  return NULL;
433 }
434 
435 
436 
438 {
439  int arr_size;
440  if ( (arr_size = p.get_array_size()) != -1 ) {
441 
442  StorageArray *storage_array = new StorageArray(tuple->size());
443  // check individual keys
444  for ( Type::Record::KeyIter it= tuple->begin(); it != tuple->end(); ++it) {
445  if ( p.down(it->key_index) ) {
446  // key on input => check & use it
447  StorageBase *storage = make_storage(p, it->type_.get());
448  if ( (typeid(*storage) == typeid(StorageNull)) && it->default_.has_value_at_declaration() ) {
449  delete storage;
450  storage = make_storage_from_default( it->default_.value(), it->type_ );
451  }
452  storage_array->new_item( it->key_index, storage );
453  p.up();
454  } else {
455  // key not on input
456  if (it->default_.is_obligatory() ) {
457  stringstream ss;
458  ss << tuple->obligatory_keys_count();
459  THROW( ExcInputError()
460  << EI_Specification("Too small size of '" + p.get_node_type(ValueTypes::array_type) + "' defining Tuple with "
461  + ss.str() + " obligatory keys.")
462  << EI_ErrorAddress(p.as_string())
463  << EI_InputType(tuple->desc()) );
464  } else if (it->default_.has_value_at_declaration() ) {
465  storage_array->new_item(it->key_index,
466  make_storage_from_default( it->default_.value(), it->type_ ) );
467  } else { // default - optional or default at read time
468  // set null
469  storage_array->new_item(it->key_index, new StorageNull() );
470  }
471  }
472  }
473 
474  FEAL_ASSERT( arr_size <= (int)tuple->size() )(arr_size)(tuple->size())(tuple->type_name()).warning("Unprocessed keys in tuple");
475 
476  return storage_array;
477 
478  } else {
479  return make_storage(p, static_cast<const Type::Record *>(tuple) );
480  }
481 }
482 
483 
484 
486 {
487  if ( try_transpose_read_ && p.is_array_type() ) {
488  // transpose auto-conversion for array type
489  return this->make_transposed_storage(p, selection);
490  }
491  string item_name;
492  try {
493  item_name = p.get_string_value();
494  int value = selection->name_to_int( item_name );
495  return new StorageInt( value );
496  } catch (ExcInputError & e) {
497  e << EI_Specification("The value should be '" + p.get_node_type(ValueTypes::str_type) + "', but we found: ");
498  e << EI_ErrorAddress(p.as_string());
499  e << EI_JSON_Type( p.get_node_type(p.get_node_type_index()) );
500  e << EI_InputType(selection->desc());
501  throw;
502  } catch (Type::Selection::ExcSelectionKeyNotFound &exc) {
503  THROW( ExcInputError() << EI_Specification("Wrong value '" + item_name + "' of the Selection.")
504  << EI_ErrorAddress(p.as_string()) << EI_JSON_Type( "" ) << EI_InputType(selection->desc()) );
505  }
506 
507  return NULL;
508 }
509 
510 
511 
513 {
514  if ( try_transpose_read_ && p.is_array_type() ) {
515  // transpose auto-conversion for array type
516  return this->make_transposed_storage(p, bool_type);
517  }
518  try {
519  return new StorageBool( p.get_bool_value() );
520  }
521  catch (ExcInputError & e) {
522  e << EI_Specification("The value should be '" + p.get_node_type(ValueTypes::bool_type) + "', but we found: ");
523  e << EI_JSON_Type( p.get_node_type(p.get_node_type_index()) );
524  e << EI_ErrorAddress(p.as_string());
525  e << EI_InputType(bool_type->desc());
526  throw;
527  }
528  return NULL;
529 }
530 
531 
532 
534 {
535  if ( try_transpose_read_ && p.is_array_type() ) {
536  // transpose auto-conversion for array type
537  return this->make_transposed_storage(p, int_type);
538  }
539  std::int64_t value;
540  try {
541  value = p.get_int_value();
542  }
543  catch (ExcInputError & e) {
544  e << EI_Specification("The value should be '" + p.get_node_type(ValueTypes::int_type) + "', but we found: ");
545  e << EI_ErrorAddress(p.as_string());
546  e << EI_JSON_Type( p.get_node_type(p.get_node_type_index()) );
547  e << EI_InputType(int_type->desc());
548  throw;
549  }
550 
551  if ( int_type->match(value) )
552  {
553  return new StorageInt( value );
554  } else {
555  THROW( ExcInputError() << EI_Specification("Value out of bounds.") << EI_ErrorAddress(p.as_string())
556  << EI_InputType(int_type->desc()) );
557  }
558 
559  return NULL;
560 }
561 
562 
563 
565 {
566  if ( try_transpose_read_ && p.is_array_type() ) {
567  // transpose auto-conversion for array type
568  return this->make_transposed_storage(p, double_type);
569  }
570  double value;
571 
572  try {
573  value = p.get_double_value();
574  }
575  catch (ExcInputError & e) {
576  e << EI_Specification("The value should be '" + p.get_node_type(ValueTypes::real_type) + "', but we found: ");
577  e << EI_ErrorAddress(p.as_string());
578  e << EI_JSON_Type( p.get_node_type(p.get_node_type_index()) );
579  e << EI_InputType(double_type->desc());
580  throw;
581  }
582 
583  if (double_type->match(value)) {
584  return new StorageDouble( value );
585  } else {
586  THROW( ExcInputError() << EI_Specification("Value out of bounds.") << EI_ErrorAddress(p.as_string())
587  << EI_InputType(double_type->desc()) );
588  }
589 
590  return NULL;
591 }
592 
593 
594 
596 {
597  if ( try_transpose_read_ && p.is_array_type() ) {
598  // transpose auto-conversion for array type
599  return this->make_transposed_storage(p, string_type);
600  }
601  string value;
602  try {
603  value = p.get_string_value();
604  }
605  catch (ExcInputError & e) {
606  if (try_transpose_read_) {
607  return this->make_transposed_storage(p, string_type);
608  }
609  e << EI_Specification("The value should be '" + p.get_node_type(ValueTypes::str_type) + "', but we found: ");
610  e << EI_ErrorAddress(p.as_string());
611  e << EI_JSON_Type( p.get_node_type(p.get_node_type_index()) );
612  e << EI_InputType(string_type->desc());
613  throw;
614  }
615 
616  if (string_type->match(value))
617  return new StorageString( value );
618  else
619  THROW( ExcInputError() << EI_Specification("Output file can not be given by absolute path: '" + value + "'")
620  << EI_ErrorAddress(p.as_string()) << EI_JSON_Type("") << EI_InputType(string_type->desc()) );
621 
622  return NULL;
623 }
624 
625 
626 
627 StorageBase * ReaderToStorage::make_storage_from_default(const string &dflt_str, std::shared_ptr<Type::TypeBase> type) {
628  try {
629  // default strings must be valid JSON
630  Type::Default dflt(dflt_str);
631  return dflt.get_storage(type);
632 
633  } catch (Input::Type::ExcWrongDefault & e) {
634  // message to distinguish exceptions thrown during Default value check at declaration
635  xprintf(Msg, "Wrong default value while reading an input stream:\n");
636  e << EI_KeyName("UNKNOWN KEY");
637  throw;
638  }
639 
640  return NULL;
641 }
642 
643 
644 
647  FEAL_DEBUG_ASSERT(p.is_array_type()).error();
648 
649  int arr_size = p.get_array_size();
650  if ( arr_size == 0 ) {
651  THROW( ExcInputError() << EI_Specification("Empty array during transpose auto-conversion.")
652  << EI_ErrorAddress(p.as_string()) << EI_InputType(type->desc()) );
653  } else {
654  if (transpose_index_ == 0) transpose_array_sizes_.push_back( arr_size );
656  StorageBase *storage = make_storage(p, type);
657  p.up();
658  return storage;
659  }
660 
661  return NULL;
662 }
663 
664 
665 
667 {
668  if ( array->match_size( 1 ) ) {
669  StorageArray *storage_array = new StorageArray(1);
670  storage_array->new_item(0, item);
671 
672  return storage_array;
673  } else {
674  THROW( ExcInputError()
675  << 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: ")
676  << EI_ErrorAddress(p.as_string()) << EI_JSON_Type( p.get_node_type(p.get_node_type_index()) ) << EI_InputType(array->desc()) );
677  }
678 
679  return NULL;
680 }
681 
682 
683 
684 /********************************************88
685  * Implementation
686  */
687 
688 template <class T>
690 {
691  FEAL_DEBUG_ASSERT(storage_!=nullptr).error();
692 
693  Address addr(storage_, root_type_);
694  // try to create an iterator just to check type
695  Iterator<T>( *root_type_, addr, 0);
696 
697  auto tmp_root_type = static_cast<const typename T::InputType &>(*root_type_);
698  return T( addr, tmp_root_type );
699 }
700 
701 
702 template ::Input::Record ReaderToStorage::get_root_interface<::Input::Record>() const;
703 template ::Input::Array ReaderToStorage::get_root_interface<::Input::Array>() const;
704 template ::Input::AbstractRecord ReaderToStorage::get_root_interface<::Input::AbstractRecord>() const;
705 template ::Input::Tuple ReaderToStorage::get_root_interface<::Input::Tuple>() const;
706 //template ReaderToStorage::get_root_interface<::Input::>()->::Input::AbstractRecord const;
707 
708 
709 } // 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.
virtual unsigned int get_node_type_index() const =0
Get index of head type, value corresponds with order in json_type_names vector.
#define FEAL_DEBUG_ASSERT(expr)
Definition of assert for debug mode only.
Definition: global_defs.h:186
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:74
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.
Definition: system.hh:59
virtual std::string get_string_value() const =0
Get string value of head node or throw exception.
unsigned int size() const
Returns number of keys in the Record.
Definition: type_record.hh:578
Class used by ReaderToStorage class to iterate over the JSON tree provided by json_spirit library...
Definition: path_json.hh:40
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:77
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
Class for declaration of the input of type Bool.
Definition: type_base.hh:429
Base abstract class used by ReaderToStorage class to iterate over the input tree. ...
Definition: path_base.hh:39
virtual bool is_array_type() const =0
Check if type of head node is array.
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.
string type_name() const override
Implements Type::TypeBase::type_name.
Definition: type_record.cc:284
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
#define FEAL_ASSERT(expr)
Definition of assert for debug and release mode.
Definition: global_defs.h:176
StorageBase * make_storage(PathBase &p, const Type::TypeBase *type)
Create storage of given type.
virtual std::string get_descendant_name() const =0
Gets name of descendant of Abstract.
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
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:460
KeyIter begin() const
Container-like access to the keys of the Record.
Definition: type_record.hh:555
Class for declaration of inputs sequences.
Definition: type_base.hh:316
StorageBase * abstract_automatic_conversion(PathBase &p, const Type::Abstract *abstr_rec)
Apply automatic conversion of Type::Abstract type.
virtual bool get_bool_value() const =0
Get boolean value of head node or throw exception.
Class for declaration of the input data that are floating point numbers.
Definition: type_base.hh:513
bool match(std::int64_t value) const
Check valid value of Integer.
Definition: type_base.cc:330
Definition: system.hh:59
static void lazy_finish()
Finishes all types registered in type repositories.
Definition: type_base.cc:85
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:362
#define xprintf(...)
Definition: system.hh:87
ReaderToStorage()
Default constructor.
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:378
virtual int get_array_size() const =0
Get size of array (sequence type), if object is not array return -1.
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
Dedicated class for storing path to input and output files.
Definition: file_path.hh:42
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:439
Tuple type proxy class.
Definition: type_tuple.hh:41
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.
virtual bool is_record_type() const =0
Check if type of head node is record.
KeyIter end() const
Container-like access to the keys of the Record.
Definition: type_record.hh:563
const TypeBase & get_sub_type() const
Getter for the type of array items.
Definition: type_base.hh:374
virtual double get_double_value() const =0
Get double value of head node or throw exception.
unsigned int obligatory_keys_count() const
Return count of obligatory keys.
Definition: type_tuple.cc:117
Definition: system.hh:59
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.
virtual std::int64_t get_int_value() const =0
Get integer value of head node or throw exception.
virtual bool is_null_type() const =0
Check if type of head node is null.
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:563
#define THROW(whole_exception_expr)
Wrapper for throw. Saves the throwing point.
Definition: exceptions.hh:44
virtual string class_name() const override
Override Type::TypeBase::class_name.
Definition: type_record.hh:328
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:296
StorageBase * storage_
Storage of the read and checked input data.