20 #include <boost/iostreams/device/file.hpp> 21 #include <boost/iostreams/filtering_stream.hpp> 43 try_transpose_read_(false),
52 std::string fname = in_file;
53 std::string extension = fname.substr(fname.find_last_of(
".") + 1);
55 if (extension ==
"con") {
57 }
else if (extension ==
"yaml") {
60 THROW(ExcInputMessage() << EI_Message(
"Invalid extension of file " + fname +
".\nMust be 'con' or 'yaml'."));
81 istringstream is(str);
83 }
catch (ExcNotJSONFormat &e) {
84 e << EI_File(
"STRING: "+str);
throw;
102 std::unique_ptr<PathBase> root_path_ptr(root_path);
107 }
catch (ExcInputError &e) {
109 e << EI_Format(
"JSON");
111 e << EI_Format(
"YAML");
131 ASSERT_PTR(type).error(
"Can not dispatch, NULL pointer to TypeBase.");
146 return make_storage(p, static_cast<const Type::Tuple *>(type) );
149 return make_storage(p, static_cast<const Type::Record *>(type) );
152 return make_storage(p, static_cast<const Type::Array *>(type) );
155 if (abstract_record_type != NULL )
return make_storage(p, abstract_record_type );
165 return make_storage(p, static_cast<const Type::Integer *>(type) );
168 return make_storage(p, static_cast<const Type::Double *>(type) );
171 return make_storage(p, static_cast<const Type::Bool *>(type) );
174 return make_storage(p, static_cast<const Type::Selection *>(type) );
177 if (string_type != NULL )
return make_storage(p, string_type );
180 THROW( Type::ExcUnknownDescendant() << Type::EI_TypeName(
typeid(type).name()) );
191 if ( record_name_from_tag !=
"" ) {
192 ASSERT(record_name_from_tag == record->
type_name())(record_name_from_tag)(record->
type_name()).error(
"Inconsistent tag of record.");
194 std::set<string> keys_to_process;
197 std::set<string>::iterator set_it;
220 set_it = keys_to_process.find(
it->key_);
221 if (set_it != keys_to_process.end()) {
222 keys_to_process.erase(set_it);
225 if ( !effectively_null && p.
down(
it->key_) ) {
230 if ( obsolete_it !=
it->attributes.end()) {
231 WarningOut() <<
"Usage of the obsolete key: '" <<
it->key_ <<
"'\n" << obsolete_it -> second;
235 if ( (
typeid(*storage) ==
typeid(
StorageNull)) &&
it->default_.has_value_at_declaration() ) {
239 storage_array->
new_item(
it->key_index, storage );
243 if (
it->default_.is_obligatory() ) {
244 THROW( ExcInputError() << EI_Specification(
"Missing obligatory key '"+
it->key_ +
"'.")
245 << EI_ErrorAddress(p.
as_string()) << EI_InputType(record->
desc()) );
246 }
else if (
it->default_.has_value_at_declaration() ) {
256 for( set_it = keys_to_process.begin(); set_it != keys_to_process.end(); ++set_it) {
258 <<
" '" << p.
as_string() <<
"'." << std::endl;
261 return storage_array;
273 if ( auto_key_it != record->
end() ) {
277 if (
it == auto_key_it ) {
280 }
else if (
it->default_.has_value_at_declaration() ) {
285 ASSERT(!
it->default_.is_obligatory())(
it->key_).error(
"Obligatory key in auto-convertible Record.");
291 return storage_array;
292 }
catch (ExcInputError &e ) {
293 THROW( ExcAutomaticConversionError() << EI_RecordName(record->
type_name()) << EI_InputErrorMessage(e.what()) );
299 << EI_InputType( record->
desc()) );
310 if ( record_name ==
"" ) {
312 THROW( ExcInputError() << EI_Specification(
"Can not determine type of the Abstract.") << EI_ErrorAddress(p.
as_string())
320 }
catch (Type::Selection::ExcSelectionKeyNotFound &exc) {
321 THROW( ExcInputError() << EI_Specification(
"Wrong value '" + record_name +
"' of the Selection.")
335 if (! default_child)
THROW(ExcInputError()
336 << EI_Specification(
"Auto conversion of Abstract not allowed.\n")
338 << EI_InputType(abstr_rec->
desc())
351 for(
int idx=0; idx < arr_size; idx++) {
357 return storage_array;
362 THROW( ExcInputError()
363 << EI_Specification(
"Do not fit the size " + ss.str() +
" of the Array.")
364 << EI_ErrorAddress(p.
as_string()) << EI_InputType(array->
desc()) );
383 }
catch (ExcInputError &e) {
408 THROW( ExcInputError() << EI_Specification(
"Result of transpose auto-conversion do not fit the size " + ss.str() +
" of the Array.")
409 << EI_ErrorAddress(p.
as_string()) << EI_InputType(array->
desc()) );
414 storage_array->
new_item(0, first_item_storage);
420 }
catch (ExcInputError &e) {
430 return storage_array;
432 THROW( ExcInputError()
434 << EI_ErrorAddress(p.
as_string()) << EI_InputType(array->
desc()) );
454 if ( p.
down(
it->key_index) ) {
457 if ( (
typeid(*storage) ==
typeid(
StorageNull)) &&
it->default_.has_value_at_declaration() ) {
461 storage_array->
new_item(
it->key_index, storage );
465 if (
it->default_.is_obligatory() ) {
468 THROW( ExcInputError()
470 + ss.str() +
" obligatory keys.")
472 << EI_InputType(tuple->
desc()) );
473 }
else if (
it->default_.has_value_at_declaration() ) {
483 if ( arr_size > (
int)tuple->
size() ) {
484 WarningOut().fmt(
"Unprocessed keys in tuple '{}', tuple has {} keys but the input is specified by {} values.\n",
488 return storage_array;
491 return make_storage(p, static_cast<const Type::Record *>(tuple) );
508 }
catch (ExcInputError & e) {
512 e << EI_InputType(selection->
desc());
514 }
catch (Type::Selection::ExcSelectionKeyNotFound &exc) {
515 THROW( ExcInputError() << EI_Specification(
"Wrong value '" + item_name +
"' of the Selection.")
516 << EI_ErrorAddress(p.
as_string()) << EI_JSON_Type(
"" ) << EI_InputType(selection->
desc()) );
533 catch (ExcInputError & e) {
537 e << EI_InputType(bool_type->
desc());
555 catch (ExcInputError & e) {
559 e << EI_InputType(int_type->
desc());
563 if ( int_type->
match(value) )
567 THROW( ExcInputError() << EI_Specification(
"Value out of bounds.") << EI_ErrorAddress(p.
as_string())
568 << EI_InputType(int_type->
desc()) );
587 catch (ExcInputError & e) {
591 e << EI_InputType(double_type->
desc());
595 if (double_type->
match(value)) {
598 THROW( ExcInputError() << EI_Specification(
"Value out of bounds.") << EI_ErrorAddress(p.
as_string())
599 << EI_InputType(double_type->
desc()) );
617 catch (ExcInputError & e) {
624 e << EI_InputType(string_type->
desc());
628 if (string_type->
match(value))
631 THROW( ExcInputError() << EI_Specification(
"Output file can not be given by absolute path: '" + value +
"'")
632 << EI_ErrorAddress(p.
as_string()) << EI_JSON_Type(
"") << EI_InputType(string_type->
desc()) );
645 }
catch (Input::Type::ExcWrongDefault & e) {
647 e << Type::EI_Desc(
"Wrong default value while reading an input stream:\n");
648 e << EI_KeyName(
"UNKNOWN KEY");
650 }
catch (Input::Type::ExcWrongDefaultJSON & e) {
651 e << EI_KeyName(
"UNKNOWN KEY");
665 if ( arr_size == 0 ) {
666 THROW( ExcInputError() << EI_Specification(
"Empty array during transpose auto-conversion.")
667 << EI_ErrorAddress(p.
as_string()) << EI_InputType(type->
desc()) );
687 return storage_array;
689 THROW( ExcInputError()
690 << EI_Specification(
"During transpose auto-conversion, the conversion to the single element array not allowed. Require type: '" + p.
get_node_type(
ValueTypes::array_type) +
"'\nFound on input: ")
712 auto tmp_root_type =
static_cast<const typename T::InputType &
>(*root_type_);
713 return T( addr, tmp_root_type );
717 template ::Input::Record ReaderToStorage::get_root_interface<::Input::Record>()
const;
718 template ::Input::Array ReaderToStorage::get_root_interface<::Input::Array>()
const;
719 template ::Input::AbstractRecord ReaderToStorage::get_root_interface<::Input::AbstractRecord>()
const;
720 template ::Input::Tuple ReaderToStorage::get_root_interface<::Input::Tuple>()
const;
std::string format(CStringRef format_str, ArgList args)
#define ASSERT(expr)
Allow use shorter versions of macro names if these names is not used with external library...
static constexpr bool value
void open_stream(Stream &stream) const
Dedicated class for storing path to input and output files.
#define ASSERT_PTR(ptr)
Definition of assert macro checking non-null pointer (PTR)
#define WarningOut()
Macro defining 'warning' record of log.
#define THROW(whole_exception_expr)
Wrapper for throw. Saves the throwing point.