Flow123d  release_2.1.0-87-gfbc1563
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 
91 {
92  return storage_;
93 }
94 
95 
96 
97 void ReaderToStorage::read_stream(istream &in, const Type::TypeBase &root_type, FileFormat format)
98 {
99  ASSERT(storage_==nullptr).error();
100 
101  PathBase * root_path;
102  if (format == FileFormat::format_JSON) {
103  root_path = new PathJSON(in);
104  } else {
105  root_path = new PathYAML(in);
106  }
107 
108  // guarantee to delete root_path on function return even on exception
109  std::unique_ptr<PathBase> root_path_ptr(root_path);
110 
111  root_type_ = &root_type;
112  try {
113  storage_ = make_storage(*root_path_ptr, root_type_);
114  } catch (ExcInputError &e) {
115  if (format == FileFormat::format_JSON) {
116  e << EI_Format("JSON");
117  } else {
118  e << EI_Format("YAML");
119  }
120  throw;
121  }
122 
123  ASSERT_PTR(storage_).error();
124 }
125 
126 
127 
128 
129 
130 
131 /********************************************
132  * Implementation of private part of ReaderToStorage - make_storage dispatch
133  */
134 
135 
137 {
138  ASSERT_PTR(type).error("Can not dispatch, NULL pointer to TypeBase.");
139 
140  // find reference node, if doesn't exist return NULL
141  PathBase * ref_path = p.find_ref_node();
142  if (ref_path) {
143  // todo: mark passed references and check cyclic references
144 
145  // dereference and take data from there
146  StorageBase * storage = make_storage( *ref_path, type );
147  delete ref_path;
148  return storage;
149  }
150 
151  // dispatch types - complex types
152  if (typeid(*type) == typeid(Type::Tuple)) {
153  return make_storage(p, static_cast<const Type::Tuple *>(type) );
154  } else
155  if (typeid(*type) == typeid(Type::Record)) {
156  return make_storage(p, static_cast<const Type::Record *>(type) );
157  } else
158  if (typeid(*type) == typeid(Type::Array)) {
159  return make_storage(p, static_cast<const Type::Array *>(type) );
160  } else {
161  const Type::Abstract * abstract_record_type = dynamic_cast<const Type::Abstract *>(type);
162  if (abstract_record_type != NULL ) return make_storage(p, abstract_record_type );
163  }
164 
165  // return Null storage if there is null on the current location
166  if (p.is_null_type()) {
167  return new StorageNull();
168  }
169 
170  // dispatch types - scalar types
171  if (typeid(*type) == typeid(Type::Integer)) {
172  return make_storage(p, static_cast<const Type::Integer *>(type) );
173  } else
174  if (typeid(*type) == typeid(Type::Double)) {
175  return make_storage(p, static_cast<const Type::Double *>(type) );
176  } else
177  if (typeid(*type) == typeid(Type::Bool)) {
178  return make_storage(p, static_cast<const Type::Bool *>(type) );
179  } else
180  if (typeid(*type) == typeid(Type::Selection)) {
181  return make_storage(p, static_cast<const Type::Selection *>(type) );
182  } else {
183  const Type::String * string_type = dynamic_cast<const Type::String *>(type);
184  if (string_type != NULL ) return make_storage(p, string_type );
185 
186  // default -> error
187  THROW( Type::ExcUnknownDescendant() << Type::EI_TypeName(typeid(type).name()) );
188  }
189 
190  return new StorageNull();
191 }
192 
193 
195 {
196  // control test, check correct tag (or TYPE key) if Record is derived from Abstract
197  string record_name_from_tag = p.get_record_name();
198  if ( record_name_from_tag != "" ) {
199  ASSERT(record_name_from_tag == record->type_name())(record_name_from_tag)(record->type_name()).error("Inconsistent tag of record.");
200  }
201  std::set<string> keys_to_process;
202  bool effectively_null = p.is_effectively_null();
203  if ( p.get_record_key_set(keys_to_process) || effectively_null ) {
204  std::set<string>::iterator set_it;
205 
206  /*Type::Record::KeyIter key_it;
207  if ( record->has_key_iterator("TYPE", key_it) && record->auto_conversion_key_iter() != record->end() ) {
208  PathBase *type_path = p->clone();
209  if ( type_path.down( "TYPE" ) ) {
210  try {
211  ASSERT( type_path.get_string_value() == record->type_name() )(type_path.get_string_value())(record->type_name())
212  .error("Invalid value of TYPE key of record");
213  make_storage(type_path, key_it->type_.get() )->get_int();
214  } catch(Type::Selection::ExcSelectionKeyNotFound &e) {
215  return record_automatic_conversion(p, record);
216  }
217  }
218  else { // automatic conversion
219  return record_automatic_conversion(p, record);
220  }
221  }*/
222 
223  StorageArray *storage_array = new StorageArray(record->size());
224  // check individual keys
225  for( Type::Record::KeyIter it= record->begin(); it != record->end(); ++it) {
226  // remove processed key from keys_to_process
227  set_it = keys_to_process.find(it->key_);
228  if (set_it != keys_to_process.end()) {
229  keys_to_process.erase(set_it);
230  }
231 
232  if ( !effectively_null && p.down(it->key_) ) {
233  // key on input => check & use it
234  // check for obsolete key
235 
236  auto obsolete_it = it->attributes.find( Type::Attribute::obsolete() );
237  if ( obsolete_it != it->attributes.end()) {
238  WarningOut() << "Usage of the obsolete key: '" << it->key_ << "'\n" << obsolete_it -> second;
239  }
240 
241  StorageBase *storage = make_storage(p, it->type_.get());
242  if ( (typeid(*storage) == typeid(StorageNull)) && it->default_.has_value_at_declaration() ) {
243  delete storage;
244  storage = make_storage_from_default( it->default_.value(), it->type_ );
245  }
246  storage_array->new_item( it->key_index, storage );
247  p.up();
248  } else {
249  // key not on input
250  if (it->default_.is_obligatory() ) {
251  THROW( ExcInputError() << EI_Specification("Missing obligatory key '"+ it->key_ +"'.")
252  << EI_ErrorAddress(p.as_string()) << EI_InputType(record->desc()) );
253  } else if (it->default_.has_value_at_declaration() ) {
254  storage_array->new_item(it->key_index,
255  make_storage_from_default( it->default_.value(), it->type_ ) );
256  } else { // defalut - optional or default at read time
257  // set null
258  storage_array->new_item(it->key_index, new StorageNull() );
259  }
260  }
261  }
262 
263  for( set_it = keys_to_process.begin(); set_it != keys_to_process.end(); ++set_it) {
264  WarningOut() << "Unprocessed key '" << (*set_it) << "' in " << record->class_name()
265  << " '" << p.as_string() << "'." << std::endl;
266  }
267 
268  return storage_array;
269 
270  } else { // automatic conversion
271  return record_automatic_conversion(p, record);
272  }
273  // possibly construction of reduced record
274 }
275 
276 
278 {
279  Type::Record::KeyIter auto_key_it = record->auto_conversion_key_iter();
280  if ( auto_key_it != record->end() ) {
281  try {
282  StorageArray *storage_array = new StorageArray(record->size());
283  for( Type::Record::KeyIter it= record->begin(); it != record->end(); ++it) {
284  if ( it == auto_key_it ) {
285  // one key is initialized by input
286  storage_array->new_item(it->key_index, make_storage(p, it->type_.get()) );
287  } else if (it->default_.has_value_at_declaration() ) {
288  // other key from default values
289  storage_array->new_item(it->key_index,
290  make_storage_from_default( it->default_.value(), it->type_ ) );
291  } else { // defalut - optional or default at read time
292  ASSERT(! it->default_.is_obligatory())(it->key_).error("Obligatory key in auto-convertible Record.");
293  // set null
294  storage_array->new_item(it->key_index, new StorageNull() );
295  }
296  }
297 
298  return storage_array;
299  } catch (ExcInputError &e ) {
300  THROW( ExcAutomaticConversionError() << EI_RecordName(record->type_name()) << EI_InputErrorMessage(e.what()) );
301  }
302 
303  } else {
304  THROW( ExcInputError() << EI_Specification("The value should be '" + p.get_node_type(ValueTypes::obj_type) + "', but we found: ")
305  << EI_ErrorAddress(p.as_string()) << EI_JSON_Type( p.get_node_type(p.get_node_type_index()) )
306  << EI_InputType( record->desc()) );
307  }
308 
309  return NULL;
310 }
311 
312 
313 
315 {
316  string record_name = p.get_record_name();
317  if ( record_name == "" ) {
318  if ( ! abstr_rec->get_selection_default().has_value_at_declaration() ) {
319  THROW( ExcInputError() << EI_Specification("Can not determine type of the Abstract.") << EI_ErrorAddress(p.as_string())
320  << EI_JSON_Type( p.get_node_type(p.get_node_type_index()) ) << EI_InputType(abstr_rec->desc()) );
321  } else { // auto conversion
322  return abstract_automatic_conversion(p, abstr_rec);
323  }
324  } else {
325  try {
326  return make_storage(p, &( abstr_rec->get_descendant(record_name) ) );
327  } catch (Type::Selection::ExcSelectionKeyNotFound &exc) {
328  THROW( ExcInputError() << EI_Specification("Wrong value '" + record_name + "' of the Selection.")
329  << EI_ErrorAddress(p.as_string()) << EI_JSON_Type( "" ) << EI_InputType(abstr_rec->get_type_selection().desc()) );
330  }
331  }
332 
333  return NULL;
334 }
335 
336 
337 
339 {
340  // perform automatic conversion
341  const Type::Record *default_child = abstr_rec->get_default_descendant();
342  if (! default_child) THROW(ExcInputError()
343  << EI_Specification("Auto conversion of Abstract not allowed.\n")
344  << EI_ErrorAddress(p.as_string())
345  << EI_InputType(abstr_rec->desc())
346  );
347  return make_storage(p, default_child );
348 }
349 
350 
352 {
353  int arr_size;
354  if ( (arr_size = p.get_array_size()) != -1 ) {
355  if ( array->match_size( arr_size ) ) {
356  // copy the array and check type of values
357  StorageArray *storage_array = new StorageArray(arr_size);
358  for( int idx=0; idx < arr_size; idx++) {
359  p.down(idx);
360  const Type::TypeBase &sub_type = array->get_sub_type();
361  storage_array->new_item(idx, make_storage(p, &sub_type) );
362  p.up();
363  }
364  return storage_array;
365 
366  } else {
367  stringstream ss;
368  ss << arr_size;
369  THROW( ExcInputError()
370  << EI_Specification("Do not fit the size " + ss.str() + " of the Array.")
371  << EI_ErrorAddress(p.as_string()) << EI_InputType(array->desc()) );
372  }
373  } else {
374  // if transposition is carried, only conversion to array with one element is allowed
375  if (try_transpose_read_) {
376  // try automatic conversion to array with one element
377  const Type::TypeBase &sub_type = array->get_sub_type();
378  StorageBase *one_element_storage = make_storage(p, &sub_type);
379  return make_autoconversion_array_storage(p, array, one_element_storage);
380  } else {
381  // set variables managed transposition
382  try_transpose_read_ = true;
383  transpose_index_ = 0;
384  transpose_array_sizes_.clear();
385 
386  const Type::TypeBase &sub_type = array->get_sub_type();
387  StorageBase *first_item_storage;
388  try {
389  first_item_storage = make_storage(p, &sub_type);
390  } catch (ExcInputError &e) {
391  if ( !array->match_size(1) ) {
392  e << EI_Specification("The value should be '" + p.get_node_type(ValueTypes::array_type) + "', but we found: ");
393  }
394  e << EI_TransposeIndex(transpose_index_);
395  e << EI_TransposeAddress(p.as_string());
396  throw;
397  }
398 
399  // automatic conversion to array with one element
400  if (transpose_array_sizes_.size() == 0) {
401  try_transpose_read_ = false;
402  return make_autoconversion_array_storage(p, array, first_item_storage);
403  } else {
404 
405  // check sizes of arrays stored in transpose_array_sizes_
407  transpose_array_sizes_.end() );
408  if (transpose_array_sizes_.size() == 1) {
409  unsigned int sizes = transpose_array_sizes_[0]; // sizes of transposed
410 
411  // array size out of bounds
412  if ( !array->match_size( sizes ) ) {
413  stringstream ss;
414  ss << sizes;
415  THROW( ExcInputError() << EI_Specification("Result of transpose auto-conversion do not fit the size " + ss.str() + " of the Array.")
416  << EI_ErrorAddress(p.as_string()) << EI_InputType(array->desc()) );
417  }
418 
419  // create storage of array
420  StorageArray *storage_array = new StorageArray(sizes);
421  storage_array->new_item(0, first_item_storage);
422  if (sizes>1) {
424  while (transpose_index_ < sizes) {
425  try {
426  storage_array->new_item(transpose_index_, make_storage(p, &sub_type));
427  } catch (ExcInputError &e) {
428  e << EI_TransposeIndex(transpose_index_);
429  e << EI_TransposeAddress(p.as_string());
430  throw;
431  }
433  }
434  }
435 
436  try_transpose_read_ = false;
437  return storage_array;
438  } else {
439  THROW( ExcInputError()
440  << EI_Specification("Unequal sizes of sub-arrays during transpose auto-conversion of '" + p.get_node_type(ValueTypes::array_type) + "'")
441  << EI_ErrorAddress(p.as_string()) << EI_InputType(array->desc()) );
442  }
443  }
444  }
445 
446  }
447 
448  return NULL;
449 }
450 
451 
452 
454 {
455  int arr_size;
456  if ( (arr_size = p.get_array_size()) != -1 ) {
457 
458  StorageArray *storage_array = new StorageArray(tuple->size());
459  // check individual keys
460  for ( Type::Record::KeyIter it= tuple->begin(); it != tuple->end(); ++it) {
461  if ( p.down(it->key_index) ) {
462  // key on input => check & use it
463  StorageBase *storage = make_storage(p, it->type_.get());
464  if ( (typeid(*storage) == typeid(StorageNull)) && it->default_.has_value_at_declaration() ) {
465  delete storage;
466  storage = make_storage_from_default( it->default_.value(), it->type_ );
467  }
468  storage_array->new_item( it->key_index, storage );
469  p.up();
470  } else {
471  // key not on input
472  if (it->default_.is_obligatory() ) {
473  stringstream ss;
474  ss << tuple->obligatory_keys_count();
475  THROW( ExcInputError()
476  << EI_Specification("Too small size of '" + p.get_node_type(ValueTypes::array_type) + "' defining Tuple with "
477  + ss.str() + " obligatory keys.")
478  << EI_ErrorAddress(p.as_string())
479  << EI_InputType(tuple->desc()) );
480  } else if (it->default_.has_value_at_declaration() ) {
481  storage_array->new_item(it->key_index,
482  make_storage_from_default( it->default_.value(), it->type_ ) );
483  } else { // default - optional or default at read time
484  // set null
485  storage_array->new_item(it->key_index, new StorageNull() );
486  }
487  }
488  }
489 
490  if ( arr_size > (int)tuple->size() ) {
491  WarningOut().fmt("Unprocessed keys in tuple '{}', tuple has {} keys but the input is specified by {} values.\n",
492  p.as_string().c_str(), tuple->size(), arr_size );
493  }
494 
495  return storage_array;
496 
497  } else {
498  return make_storage(p, static_cast<const Type::Record *>(tuple) );
499  }
500 }
501 
502 
503 
505 {
506  if ( try_transpose_read_ && p.is_array_type() ) {
507  // transpose auto-conversion for array type
508  return this->make_transposed_storage(p, selection);
509  }
510  string item_name;
511  try {
512  item_name = p.get_string_value();
513  int value = selection->name_to_int( item_name );
514  return new StorageInt( value );
515  } catch (ExcInputError & e) {
516  e << EI_Specification("The value should be '" + p.get_node_type(ValueTypes::str_type) + "', but we found: ");
517  e << EI_ErrorAddress(p.as_string());
518  e << EI_JSON_Type( p.get_node_type(p.get_node_type_index()) );
519  e << EI_InputType(selection->desc());
520  throw;
521  } catch (Type::Selection::ExcSelectionKeyNotFound &exc) {
522  THROW( ExcInputError() << EI_Specification("Wrong value '" + item_name + "' of the Selection.")
523  << EI_ErrorAddress(p.as_string()) << EI_JSON_Type( "" ) << EI_InputType(selection->desc()) );
524  }
525 
526  return NULL;
527 }
528 
529 
530 
532 {
533  if ( try_transpose_read_ && p.is_array_type() ) {
534  // transpose auto-conversion for array type
535  return this->make_transposed_storage(p, bool_type);
536  }
537  try {
538  return new StorageBool( p.get_bool_value() );
539  }
540  catch (ExcInputError & e) {
541  e << EI_Specification("The value should be '" + p.get_node_type(ValueTypes::bool_type) + "', but we found: ");
542  e << EI_JSON_Type( p.get_node_type(p.get_node_type_index()) );
543  e << EI_ErrorAddress(p.as_string());
544  e << EI_InputType(bool_type->desc());
545  throw;
546  }
547  return NULL;
548 }
549 
550 
551 
553 {
554  if ( try_transpose_read_ && p.is_array_type() ) {
555  // transpose auto-conversion for array type
556  return this->make_transposed_storage(p, int_type);
557  }
558  std::int64_t value;
559  try {
560  value = p.get_int_value();
561  }
562  catch (ExcInputError & e) {
563  e << EI_Specification("The value should be '" + p.get_node_type(ValueTypes::int_type) + "', but we found: ");
564  e << EI_ErrorAddress(p.as_string());
565  e << EI_JSON_Type( p.get_node_type(p.get_node_type_index()) );
566  e << EI_InputType(int_type->desc());
567  throw;
568  }
569 
570  if ( int_type->match(value) )
571  {
572  return new StorageInt( value );
573  } else {
574  THROW( ExcInputError() << EI_Specification("Value out of bounds.") << EI_ErrorAddress(p.as_string())
575  << EI_InputType(int_type->desc()) );
576  }
577 
578  return NULL;
579 }
580 
581 
582 
584 {
585  if ( try_transpose_read_ && p.is_array_type() ) {
586  // transpose auto-conversion for array type
587  return this->make_transposed_storage(p, double_type);
588  }
589  double value;
590 
591  try {
592  value = p.get_double_value();
593  }
594  catch (ExcInputError & e) {
595  e << EI_Specification("The value should be '" + p.get_node_type(ValueTypes::real_type) + "', but we found: ");
596  e << EI_ErrorAddress(p.as_string());
597  e << EI_JSON_Type( p.get_node_type(p.get_node_type_index()) );
598  e << EI_InputType(double_type->desc());
599  throw;
600  }
601 
602  if (double_type->match(value)) {
603  return new StorageDouble( value );
604  } else {
605  THROW( ExcInputError() << EI_Specification("Value out of bounds.") << EI_ErrorAddress(p.as_string())
606  << EI_InputType(double_type->desc()) );
607  }
608 
609  return NULL;
610 }
611 
612 
613 
615 {
616  if ( try_transpose_read_ && p.is_array_type() ) {
617  // transpose auto-conversion for array type
618  return this->make_transposed_storage(p, string_type);
619  }
620  string value;
621  try {
622  value = p.get_string_value();
623  }
624  catch (ExcInputError & e) {
625  if (try_transpose_read_) {
626  return this->make_transposed_storage(p, string_type);
627  }
628  e << EI_Specification("The value should be '" + p.get_node_type(ValueTypes::str_type) + "', but we found: ");
629  e << EI_ErrorAddress(p.as_string());
630  e << EI_JSON_Type( p.get_node_type(p.get_node_type_index()) );
631  e << EI_InputType(string_type->desc());
632  throw;
633  }
634 
635  if (string_type->match(value))
636  return new StorageString( value );
637  else
638  THROW( ExcInputError() << EI_Specification("Output file can not be given by absolute path: '" + value + "'")
639  << EI_ErrorAddress(p.as_string()) << EI_JSON_Type("") << EI_InputType(string_type->desc()) );
640 
641  return NULL;
642 }
643 
644 
645 
646 StorageBase * ReaderToStorage::make_storage_from_default(const string &dflt_str, std::shared_ptr<Type::TypeBase> type) {
647  try {
648  // default strings must be valid JSON
649  Type::Default dflt(dflt_str);
650  return dflt.get_storage(type);
651 
652  } catch (Input::Type::ExcWrongDefault & e) {
653  // message to distinguish exceptions thrown during Default value check at declaration
654  e << Type::EI_Desc("Wrong default value while reading an input stream:\n");
655  e << EI_KeyName("UNKNOWN KEY");
656  throw;
657  } catch (Input::Type::ExcWrongDefaultJSON & e) {
658  e << EI_KeyName("UNKNOWN KEY");
659  throw;
660  }
661 
662  return NULL;
663 }
664 
665 
666 
668  ASSERT(try_transpose_read_).error();
669  ASSERT(p.is_array_type()).error();
670 
671  int arr_size = p.get_array_size();
672  if ( arr_size == 0 ) {
673  THROW( ExcInputError() << EI_Specification("Empty array during transpose auto-conversion.")
674  << EI_ErrorAddress(p.as_string()) << EI_InputType(type->desc()) );
675  } else {
676  if (transpose_index_ == 0) transpose_array_sizes_.push_back( arr_size );
678  StorageBase *storage = make_storage(p, type);
679  p.up();
680  return storage;
681  }
682 
683  return NULL;
684 }
685 
686 
687 
689 {
690  if ( array->match_size( 1 ) ) {
691  StorageArray *storage_array = new StorageArray(1);
692  storage_array->new_item(0, item);
693 
694  return storage_array;
695  } else {
696  THROW( ExcInputError()
697  << 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: ")
698  << EI_ErrorAddress(p.as_string()) << EI_JSON_Type( p.get_node_type(p.get_node_type_index()) ) << EI_InputType(array->desc()) );
699  }
700 
701  return NULL;
702 }
703 
704 
705 
706 /********************************************88
707  * Implementation
708  */
709 
710 template <class T>
712 {
713  ASSERT_PTR(storage_).error();
714 
715  Address addr(storage_, root_type_);
716  // try to create an iterator just to check type
717  Iterator<T>( *root_type_, addr, 0);
718 
719  auto tmp_root_type = static_cast<const typename T::InputType &>(*root_type_);
720  return T( addr, tmp_root_type );
721 }
722 
723 
724 template ::Input::Record ReaderToStorage::get_root_interface<::Input::Record>() const;
725 template ::Input::Array ReaderToStorage::get_root_interface<::Input::Array>() const;
726 template ::Input::AbstractRecord ReaderToStorage::get_root_interface<::Input::AbstractRecord>() const;
727 template ::Input::Tuple ReaderToStorage::get_root_interface<::Input::Tuple>() const;
728 //template ReaderToStorage::get_root_interface<::Input::>()->::Input::AbstractRecord const;
729 
730 
731 } // 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:211
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:593
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:313
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.
virtual FinishStatus finish(FinishStatus finish_type=FinishStatus::regular_)
Finish method. Finalize construction of "Lazy types": Record, Selection, Abstract and generic type...
Definition: type_base.cc:192
Class Input::Type::Default specifies default value of keys of a Input::Type::Record.
Definition: type_record.hh:56
Class for declaration of the input of type Bool.
Definition: type_base.hh:452
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 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:483
KeyIter begin() const
Container-like access to the keys of the Record.
Definition: type_record.hh:570
StorageBase * get_storage()
Getter for root of the storage tree.
Class for declaration of inputs sequences.
Definition: type_base.hh:339
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:534
bool match(std::int64_t value) const
Check valid value of Integer.
Definition: type_base.cc:424
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:84
bool match(double value) const
Returns true if the given integer value conforms to the Type::Double bounds.
Definition: type_base.cc:466
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:401
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:127
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
virtual string class_name() const override
Override Type::TypeBase::class_name.
Definition: type_record.cc:319
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:597
Tuple type proxy class.
Definition: type_tuple.hh:45
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:578
const TypeBase & get_sub_type() const
Getter for the type of array items.
Definition: type_base.hh:397
#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:135
Record type proxy class.
Definition: type_record.hh:177
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:582
#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:331
StorageBase * storage_
Storage of the read and checked input data.