Flow123d  last_with_con_2.0.0-4-g42e6930
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 
49 ReaderToStorage::ReaderToStorage(const FilePath &in_file, const Type::TypeBase &root_type)
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 all lazy input types
68 
69  read_stream(in, root_type, format);
70 }
71 
72 
73 
74 ReaderToStorage::ReaderToStorage( const string &str, const Type::TypeBase &root_type, FileFormat format)
76 {
77  // finish all lazy input types
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  std::set<string> keys_to_process;
190  bool effectively_null = p.is_effectively_null();
191  if ( p.get_record_key_set(keys_to_process) || effectively_null ) {
192  std::set<string>::iterator set_it;
193 
194  /*Type::Record::KeyIter key_it;
195  if ( record->has_key_iterator("TYPE", key_it) && record->auto_conversion_key_iter() != record->end() ) {
196  PathBase *type_path = p->clone();
197  if ( type_path.down( "TYPE" ) ) {
198  try {
199  ASSERT( type_path.get_string_value() == record->type_name() )(type_path.get_string_value())(record->type_name())
200  .error("Invalid value of TYPE key of record");
201  make_storage(type_path, key_it->type_.get() )->get_int();
202  } catch(Type::Selection::ExcSelectionKeyNotFound &e) {
203  return record_automatic_conversion(p, record);
204  }
205  }
206  else { // automatic conversion
207  return record_automatic_conversion(p, record);
208  }
209  }*/
210 
211  StorageArray *storage_array = new StorageArray(record->size());
212  // check individual keys
213  for( Type::Record::KeyIter it= record->begin(); it != record->end(); ++it) {
214  // remove processed key from keys_to_process
215  set_it = keys_to_process.find(it->key_);
216  if (set_it != keys_to_process.end()) {
217  keys_to_process.erase(set_it);
218  }
219 
220  if ( !effectively_null && p.down(it->key_) ) {
221  // key on input => check & use it
222  // check for obsolete key
223 
224  auto obsolete_it = it->attributes.find( Type::Attribute::obsolete() );
225  if ( obsolete_it != it->attributes.end()) {
226  WarningOut() << "Usage of the obsolete key: '" << it->key_ << "'\n" << obsolete_it -> second;
227  }
228 
229  StorageBase *storage = make_storage(p, it->type_.get());
230  if ( (typeid(*storage) == typeid(StorageNull)) && it->default_.has_value_at_declaration() ) {
231  delete storage;
232  storage = make_storage_from_default( it->default_.value(), it->type_ );
233  }
234  storage_array->new_item( it->key_index, storage );
235  p.up();
236  } else {
237  // key not on input
238  if (it->default_.is_obligatory() ) {
239  THROW( ExcInputError() << EI_Specification("Missing obligatory key '"+ it->key_ +"'.")
240  << EI_ErrorAddress(p.as_string()) << EI_InputType(record->desc()) );
241  } else if (it->default_.has_value_at_declaration() ) {
242  storage_array->new_item(it->key_index,
243  make_storage_from_default( it->default_.value(), it->type_ ) );
244  } else { // defalut - optional or default at read time
245  // set null
246  storage_array->new_item(it->key_index, new StorageNull() );
247  }
248  }
249  }
250 
251  for( set_it = keys_to_process.begin(); set_it != keys_to_process.end(); ++set_it) {
252  WarningOut() << "Unprocessed key '" << (*set_it) << "' in " << record->class_name()
253  << " '" << p.as_string() << "'." << std::endl;
254  }
255 
256  return storage_array;
257 
258  } else { // automatic conversion
259  return record_automatic_conversion(p, record);
260  }
261  // possibly construction of reduced record
262 }
263 
264 
266 {
267  Type::Record::KeyIter auto_key_it = record->auto_conversion_key_iter();
268  if ( auto_key_it != record->end() ) {
269  try {
270  StorageArray *storage_array = new StorageArray(record->size());
271  for( Type::Record::KeyIter it= record->begin(); it != record->end(); ++it) {
272  if ( it == auto_key_it ) {
273  // one key is initialized by input
274  storage_array->new_item(it->key_index, make_storage(p, it->type_.get()) );
275  } else if (it->default_.has_value_at_declaration() ) {
276  // other key from default values
277  storage_array->new_item(it->key_index,
278  make_storage_from_default( it->default_.value(), it->type_ ) );
279  } else { // defalut - optional or default at read time
280  ASSERT(! it->default_.is_obligatory())(it->key_).error("Obligatory key in auto-convertible Record.");
281  // set null
282  storage_array->new_item(it->key_index, new StorageNull() );
283  }
284  }
285 
286  return storage_array;
287  } catch (ExcInputError &e ) {
288  THROW( ExcAutomaticConversionError() << EI_RecordName(record->type_name()) << EI_InputErrorMessage(e.what()) );
289  }
290 
291  } else {
292  THROW( ExcInputError() << EI_Specification("The value should be '" + p.get_node_type(ValueTypes::obj_type) + "', but we found: ")
293  << EI_ErrorAddress(p.as_string()) << EI_JSON_Type( p.get_node_type(p.get_node_type_index()) )
294  << EI_InputType( record->desc()) );
295  }
296 
297  return NULL;
298 }
299 
300 
301 
303 {
304  if ( p.is_record_type() ) {
305 
306  string descendant_name = p.get_descendant_name();
307  if ( descendant_name == "" ) {
308  if ( ! abstr_rec->get_selection_default().has_value_at_declaration() ) {
309  THROW( ExcInputError() << EI_Specification("Missing key 'TYPE' in Abstract.") << EI_ErrorAddress(p.as_string()) << EI_InputType(abstr_rec->desc()) );
310  } else { // auto conversion
311  return abstract_automatic_conversion(p, abstr_rec);
312  }
313  } else {
314  try {
315  return make_storage(p, &( abstr_rec->get_descendant(descendant_name) ) );
316  } catch (Type::Selection::ExcSelectionKeyNotFound &exc) {
317  THROW( ExcInputError() << EI_Specification("Wrong value '" + descendant_name + "' of the Selection.")
318  << EI_ErrorAddress(p.as_string()) << EI_JSON_Type( "" ) << EI_InputType(abstr_rec->get_type_selection().desc()) );
319  }
320  }
321  } else {
322  if ( ! abstr_rec->get_selection_default().has_value_at_declaration() ) {
323  THROW( ExcInputError() << EI_Specification("The value should be '" + p.get_node_type(ValueTypes::obj_type) + "', but we found: ")
324  << EI_ErrorAddress(p.as_string()) << EI_JSON_Type( p.get_node_type(p.get_node_type_index()) ) << EI_InputType(abstr_rec->desc()) );
325  } else { // auto conversion
326  return abstract_automatic_conversion(p, abstr_rec);
327  }
328  }
329 
330  return NULL;
331 }
332 
333 
334 
336 {
337  // perform automatic conversion
338  const Type::Record *default_child = abstr_rec->get_default_descendant();
339  if (! default_child) THROW(ExcInputError()
340  << EI_Specification("Auto conversion of Abstract not allowed.\n")
341  << EI_ErrorAddress(p.as_string())
342  << EI_InputType(abstr_rec->desc())
343  );
344  return make_storage(p, default_child );
345 }
346 
347 
349 {
350  int arr_size;
351  if ( (arr_size = p.get_array_size()) != -1 ) {
352  if ( array->match_size( arr_size ) ) {
353  // copy the array and check type of values
354  StorageArray *storage_array = new StorageArray(arr_size);
355  for( int idx=0; idx < arr_size; idx++) {
356  p.down(idx);
357  const Type::TypeBase &sub_type = array->get_sub_type();
358  storage_array->new_item(idx, make_storage(p, &sub_type) );
359  p.up();
360  }
361  return storage_array;
362 
363  } else {
364  stringstream ss;
365  ss << arr_size;
366  THROW( ExcInputError()
367  << EI_Specification("Do not fit the size " + ss.str() + " of the Array.")
368  << EI_ErrorAddress(p.as_string()) << EI_InputType(array->desc()) );
369  }
370  } else {
371  // if transposition is carried, only conversion to array with one element is allowed
372  if (try_transpose_read_) {
373  // try automatic conversion to array with one element
374  const Type::TypeBase &sub_type = array->get_sub_type();
375  StorageBase *one_element_storage = make_storage(p, &sub_type);
376  return make_autoconversion_array_storage(p, array, one_element_storage);
377  } else {
378  // set variables managed transposition
379  try_transpose_read_ = true;
380  transpose_index_ = 0;
381  transpose_array_sizes_.clear();
382 
383  const Type::TypeBase &sub_type = array->get_sub_type();
384  StorageBase *first_item_storage;
385  try {
386  first_item_storage = make_storage(p, &sub_type);
387  } catch (ExcInputError &e) {
388  if ( !array->match_size(1) ) {
389  e << EI_Specification("The value should be '" + p.get_node_type(ValueTypes::array_type) + "', but we found: ");
390  }
391  e << EI_TransposeIndex(transpose_index_);
392  e << EI_TransposeAddress(p.as_string());
393  throw;
394  }
395 
396  // automatic conversion to array with one element
397  if (transpose_array_sizes_.size() == 0) {
398  try_transpose_read_ = false;
399  return make_autoconversion_array_storage(p, array, first_item_storage);
400  } else {
401 
402  // check sizes of arrays stored in transpose_array_sizes_
404  transpose_array_sizes_.end() );
405  if (transpose_array_sizes_.size() == 1) {
406  unsigned int sizes = transpose_array_sizes_[0]; // sizes of transposed
407 
408  // array size out of bounds
409  if ( !array->match_size( sizes ) ) {
410  stringstream ss;
411  ss << sizes;
412  THROW( ExcInputError() << EI_Specification("Result of transpose auto-conversion do not fit the size " + ss.str() + " of the Array.")
413  << EI_ErrorAddress(p.as_string()) << EI_InputType(array->desc()) );
414  }
415 
416  // create storage of array
417  StorageArray *storage_array = new StorageArray(sizes);
418  storage_array->new_item(0, first_item_storage);
419  if (sizes>1) {
421  while (transpose_index_ < sizes) {
422  try {
423  storage_array->new_item(transpose_index_, make_storage(p, &sub_type));
424  } catch (ExcInputError &e) {
425  e << EI_TransposeIndex(transpose_index_);
426  e << EI_TransposeAddress(p.as_string());
427  throw;
428  }
430  }
431  }
432 
433  try_transpose_read_ = false;
434  return storage_array;
435  } else {
436  THROW( ExcInputError()
437  << EI_Specification("Unequal sizes of sub-arrays during transpose auto-conversion of '" + p.get_node_type(ValueTypes::array_type) + "'")
438  << EI_ErrorAddress(p.as_string()) << EI_InputType(array->desc()) );
439  }
440  }
441  }
442 
443  }
444 
445  return NULL;
446 }
447 
448 
449 
451 {
452  int arr_size;
453  if ( (arr_size = p.get_array_size()) != -1 ) {
454 
455  StorageArray *storage_array = new StorageArray(tuple->size());
456  // check individual keys
457  for ( Type::Record::KeyIter it= tuple->begin(); it != tuple->end(); ++it) {
458  if ( p.down(it->key_index) ) {
459  // key on input => check & use it
460  StorageBase *storage = make_storage(p, it->type_.get());
461  if ( (typeid(*storage) == typeid(StorageNull)) && it->default_.has_value_at_declaration() ) {
462  delete storage;
463  storage = make_storage_from_default( it->default_.value(), it->type_ );
464  }
465  storage_array->new_item( it->key_index, storage );
466  p.up();
467  } else {
468  // key not on input
469  if (it->default_.is_obligatory() ) {
470  stringstream ss;
471  ss << tuple->obligatory_keys_count();
472  THROW( ExcInputError()
473  << EI_Specification("Too small size of '" + p.get_node_type(ValueTypes::array_type) + "' defining Tuple with "
474  + ss.str() + " obligatory keys.")
475  << EI_ErrorAddress(p.as_string())
476  << EI_InputType(tuple->desc()) );
477  } else if (it->default_.has_value_at_declaration() ) {
478  storage_array->new_item(it->key_index,
479  make_storage_from_default( it->default_.value(), it->type_ ) );
480  } else { // default - optional or default at read time
481  // set null
482  storage_array->new_item(it->key_index, new StorageNull() );
483  }
484  }
485  }
486 
487  if ( arr_size > (int)tuple->size() ) {
488  WarningOut().fmt("Unprocessed keys in tuple '{}', tuple has {} keys but the input is specified by {} values.\n",
489  p.as_string().c_str(), tuple->size(), arr_size );
490  }
491 
492  return storage_array;
493 
494  } else {
495  return make_storage(p, static_cast<const Type::Record *>(tuple) );
496  }
497 }
498 
499 
500 
502 {
503  if ( try_transpose_read_ && p.is_array_type() ) {
504  // transpose auto-conversion for array type
505  return this->make_transposed_storage(p, selection);
506  }
507  string item_name;
508  try {
509  item_name = p.get_string_value();
510  int value = selection->name_to_int( item_name );
511  return new StorageInt( value );
512  } catch (ExcInputError & e) {
513  e << EI_Specification("The value should be '" + p.get_node_type(ValueTypes::str_type) + "', but we found: ");
514  e << EI_ErrorAddress(p.as_string());
515  e << EI_JSON_Type( p.get_node_type(p.get_node_type_index()) );
516  e << EI_InputType(selection->desc());
517  throw;
518  } catch (Type::Selection::ExcSelectionKeyNotFound &exc) {
519  THROW( ExcInputError() << EI_Specification("Wrong value '" + item_name + "' of the Selection.")
520  << EI_ErrorAddress(p.as_string()) << EI_JSON_Type( "" ) << EI_InputType(selection->desc()) );
521  }
522 
523  return NULL;
524 }
525 
526 
527 
529 {
530  if ( try_transpose_read_ && p.is_array_type() ) {
531  // transpose auto-conversion for array type
532  return this->make_transposed_storage(p, bool_type);
533  }
534  try {
535  return new StorageBool( p.get_bool_value() );
536  }
537  catch (ExcInputError & e) {
538  e << EI_Specification("The value should be '" + p.get_node_type(ValueTypes::bool_type) + "', but we found: ");
539  e << EI_JSON_Type( p.get_node_type(p.get_node_type_index()) );
540  e << EI_ErrorAddress(p.as_string());
541  e << EI_InputType(bool_type->desc());
542  throw;
543  }
544  return NULL;
545 }
546 
547 
548 
550 {
551  if ( try_transpose_read_ && p.is_array_type() ) {
552  // transpose auto-conversion for array type
553  return this->make_transposed_storage(p, int_type);
554  }
555  std::int64_t value;
556  try {
557  value = p.get_int_value();
558  }
559  catch (ExcInputError & e) {
560  e << EI_Specification("The value should be '" + p.get_node_type(ValueTypes::int_type) + "', but we found: ");
561  e << EI_ErrorAddress(p.as_string());
562  e << EI_JSON_Type( p.get_node_type(p.get_node_type_index()) );
563  e << EI_InputType(int_type->desc());
564  throw;
565  }
566 
567  if ( int_type->match(value) )
568  {
569  return new StorageInt( value );
570  } else {
571  THROW( ExcInputError() << EI_Specification("Value out of bounds.") << EI_ErrorAddress(p.as_string())
572  << EI_InputType(int_type->desc()) );
573  }
574 
575  return NULL;
576 }
577 
578 
579 
581 {
582  if ( try_transpose_read_ && p.is_array_type() ) {
583  // transpose auto-conversion for array type
584  return this->make_transposed_storage(p, double_type);
585  }
586  double value;
587 
588  try {
589  value = p.get_double_value();
590  }
591  catch (ExcInputError & e) {
592  e << EI_Specification("The value should be '" + p.get_node_type(ValueTypes::real_type) + "', but we found: ");
593  e << EI_ErrorAddress(p.as_string());
594  e << EI_JSON_Type( p.get_node_type(p.get_node_type_index()) );
595  e << EI_InputType(double_type->desc());
596  throw;
597  }
598 
599  if (double_type->match(value)) {
600  return new StorageDouble( value );
601  } else {
602  THROW( ExcInputError() << EI_Specification("Value out of bounds.") << EI_ErrorAddress(p.as_string())
603  << EI_InputType(double_type->desc()) );
604  }
605 
606  return NULL;
607 }
608 
609 
610 
612 {
613  if ( try_transpose_read_ && p.is_array_type() ) {
614  // transpose auto-conversion for array type
615  return this->make_transposed_storage(p, string_type);
616  }
617  string value;
618  try {
619  value = p.get_string_value();
620  }
621  catch (ExcInputError & e) {
622  if (try_transpose_read_) {
623  return this->make_transposed_storage(p, string_type);
624  }
625  e << EI_Specification("The value should be '" + p.get_node_type(ValueTypes::str_type) + "', but we found: ");
626  e << EI_ErrorAddress(p.as_string());
627  e << EI_JSON_Type( p.get_node_type(p.get_node_type_index()) );
628  e << EI_InputType(string_type->desc());
629  throw;
630  }
631 
632  if (string_type->match(value))
633  return new StorageString( value );
634  else
635  THROW( ExcInputError() << EI_Specification("Output file can not be given by absolute path: '" + value + "'")
636  << EI_ErrorAddress(p.as_string()) << EI_JSON_Type("") << EI_InputType(string_type->desc()) );
637 
638  return NULL;
639 }
640 
641 
642 
643 StorageBase * ReaderToStorage::make_storage_from_default(const string &dflt_str, std::shared_ptr<Type::TypeBase> type) {
644  try {
645  // default strings must be valid JSON
646  Type::Default dflt(dflt_str);
647  return dflt.get_storage(type);
648 
649  } catch (Input::Type::ExcWrongDefault & e) {
650  // message to distinguish exceptions thrown during Default value check at declaration
651  e << Type::EI_Desc("Wrong default value while reading an input stream:\n");
652  e << EI_KeyName("UNKNOWN KEY");
653  throw;
654  } catch (Input::Type::ExcWrongDefaultJSON & e) {
655  e << EI_KeyName("UNKNOWN KEY");
656  throw;
657  }
658 
659  return NULL;
660 }
661 
662 
663 
665  ASSERT(try_transpose_read_).error();
666  ASSERT(p.is_array_type()).error();
667 
668  int arr_size = p.get_array_size();
669  if ( arr_size == 0 ) {
670  THROW( ExcInputError() << EI_Specification("Empty array during transpose auto-conversion.")
671  << EI_ErrorAddress(p.as_string()) << EI_InputType(type->desc()) );
672  } else {
673  if (transpose_index_ == 0) transpose_array_sizes_.push_back( arr_size );
675  StorageBase *storage = make_storage(p, type);
676  p.up();
677  return storage;
678  }
679 
680  return NULL;
681 }
682 
683 
684 
686 {
687  if ( array->match_size( 1 ) ) {
688  StorageArray *storage_array = new StorageArray(1);
689  storage_array->new_item(0, item);
690 
691  return storage_array;
692  } else {
693  THROW( ExcInputError()
694  << 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: ")
695  << EI_ErrorAddress(p.as_string()) << EI_JSON_Type( p.get_node_type(p.get_node_type_index()) ) << EI_InputType(array->desc()) );
696  }
697 
698  return NULL;
699 }
700 
701 
702 
703 /********************************************88
704  * Implementation
705  */
706 
707 template <class T>
709 {
710  ASSERT_PTR(storage_).error();
711 
712  Address addr(storage_, root_type_);
713  // try to create an iterator just to check type
714  Iterator<T>( *root_type_, addr, 0);
715 
716  auto tmp_root_type = static_cast<const typename T::InputType &>(*root_type_);
717  return T( addr, tmp_root_type );
718 }
719 
720 
721 template ::Input::Record ReaderToStorage::get_root_interface<::Input::Record>() const;
722 template ::Input::Array ReaderToStorage::get_root_interface<::Input::Array>() const;
723 template ::Input::AbstractRecord ReaderToStorage::get_root_interface<::Input::AbstractRecord>() const;
724 template ::Input::Tuple ReaderToStorage::get_root_interface<::Input::Tuple>() const;
725 //template ReaderToStorage::get_root_interface<::Input::>()->::Input::AbstractRecord const;
726 
727 
728 } // 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.
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:79
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.
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:582
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:434
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:299
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
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.
#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
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:465
KeyIter begin() const
Container-like access to the keys of the Record.
Definition: type_record.hh:559
Class for declaration of inputs sequences.
Definition: type_base.hh:321
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.
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:518
bool match(std::int64_t value) const
Check valid value of Integer.
Definition: type_base.cc:330
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:88
bool match(double value) const
Returns true if the given integer value conforms to the Type::Double bounds.
Definition: type_base.cc:362
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:383
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: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: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.
#define ASSERT_PTR(ptr)
Definition of assert macro checking non-null pointer (PTR)
Definition: asserts.hh:336
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:567
const TypeBase & get_sub_type() const
Getter for the type of array items.
Definition: type_base.hh:379
virtual double get_double_value() const =0
Get double value of head node or throw exception.
#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:117
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.
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:568
#define THROW(whole_exception_expr)
Wrapper for throw. Saves the throwing point.
Definition: exceptions.hh:45
virtual string class_name() const override
Override Type::TypeBase::class_name.
Definition: type_record.hh:332
Template for classes storing finite set of named values.
virtual bool is_effectively_null() const =0
Check empty Input Type Record, necessary for correct proccess of YAML output, for JSON has no effect...
KeyIter auto_conversion_key_iter() const
Returns iterator to auto-conversion key.
Definition: type_record.cc:311
StorageBase * storage_
Storage of the read and checked input data.