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;
109 std::unique_ptr<PathBase> root_path_ptr(root_path);
114 }
catch (ExcInputError &e) {
116 e << EI_Format(
"JSON");
118 e << EI_Format(
"YAML");
138 ASSERT_PTR(type).error(
"Can not dispatch, NULL pointer to TypeBase.");
153 return make_storage(p, static_cast<const Type::Tuple *>(type) );
156 return make_storage(p, static_cast<const Type::Record *>(type) );
159 return make_storage(p, static_cast<const Type::Array *>(type) );
162 if (abstract_record_type != NULL )
return make_storage(p, abstract_record_type );
172 return make_storage(p, static_cast<const Type::Integer *>(type) );
175 return make_storage(p, static_cast<const Type::Double *>(type) );
178 return make_storage(p, static_cast<const Type::Bool *>(type) );
181 return make_storage(p, static_cast<const Type::Selection *>(type) );
184 if (string_type != NULL )
return make_storage(p, string_type );
187 THROW( Type::ExcUnknownDescendant() << Type::EI_TypeName(
typeid(type).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.");
201 std::set<string> keys_to_process;
204 std::set<string>::iterator set_it;
227 set_it = keys_to_process.find(
it->key_);
228 if (set_it != keys_to_process.end()) {
229 keys_to_process.erase(set_it);
232 if ( !effectively_null && p.
down(
it->key_) ) {
237 if ( obsolete_it !=
it->attributes.end()) {
238 WarningOut() <<
"Usage of the obsolete key: '" <<
it->key_ <<
"'\n" << obsolete_it -> second;
242 if ( (
typeid(*storage) ==
typeid(
StorageNull)) &&
it->default_.has_value_at_declaration() ) {
246 storage_array->
new_item(
it->key_index, storage );
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() ) {
263 for( set_it = keys_to_process.begin(); set_it != keys_to_process.end(); ++set_it) {
265 <<
" '" << p.
as_string() <<
"'." << std::endl;
268 return storage_array;
280 if ( auto_key_it != record->
end() ) {
284 if (
it == auto_key_it ) {
287 }
else if (
it->default_.has_value_at_declaration() ) {
292 ASSERT(!
it->default_.is_obligatory())(
it->key_).error(
"Obligatory key in auto-convertible Record.");
298 return storage_array;
299 }
catch (ExcInputError &e ) {
300 THROW( ExcAutomaticConversionError() << EI_RecordName(record->
type_name()) << EI_InputErrorMessage(e.what()) );
306 << EI_InputType( record->
desc()) );
317 if ( record_name ==
"" ) {
319 THROW( ExcInputError() << EI_Specification(
"Can not determine type of the Abstract.") << EI_ErrorAddress(p.
as_string())
327 }
catch (Type::Selection::ExcSelectionKeyNotFound &exc) {
328 THROW( ExcInputError() << EI_Specification(
"Wrong value '" + record_name +
"' of the Selection.")
342 if (! default_child)
THROW(ExcInputError()
343 << EI_Specification(
"Auto conversion of Abstract not allowed.\n")
345 << EI_InputType(abstr_rec->
desc())
358 for(
int idx=0; idx < arr_size; idx++) {
364 return storage_array;
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()) );
390 }
catch (ExcInputError &e) {
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()) );
421 storage_array->
new_item(0, first_item_storage);
427 }
catch (ExcInputError &e) {
437 return storage_array;
439 THROW( ExcInputError()
441 << EI_ErrorAddress(p.
as_string()) << EI_InputType(array->
desc()) );
461 if ( p.
down(
it->key_index) ) {
464 if ( (
typeid(*storage) ==
typeid(
StorageNull)) &&
it->default_.has_value_at_declaration() ) {
468 storage_array->
new_item(
it->key_index, storage );
472 if (
it->default_.is_obligatory() ) {
475 THROW( ExcInputError()
477 + ss.str() +
" obligatory keys.")
479 << EI_InputType(tuple->
desc()) );
480 }
else if (
it->default_.has_value_at_declaration() ) {
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",
495 return storage_array;
498 return make_storage(p, static_cast<const Type::Record *>(tuple) );
515 }
catch (ExcInputError & e) {
519 e << EI_InputType(selection->
desc());
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()) );
540 catch (ExcInputError & e) {
544 e << EI_InputType(bool_type->
desc());
562 catch (ExcInputError & e) {
566 e << EI_InputType(int_type->
desc());
570 if ( int_type->
match(value) )
574 THROW( ExcInputError() << EI_Specification(
"Value out of bounds.") << EI_ErrorAddress(p.
as_string())
575 << EI_InputType(int_type->
desc()) );
594 catch (ExcInputError & e) {
598 e << EI_InputType(double_type->
desc());
602 if (double_type->
match(value)) {
605 THROW( ExcInputError() << EI_Specification(
"Value out of bounds.") << EI_ErrorAddress(p.
as_string())
606 << EI_InputType(double_type->
desc()) );
624 catch (ExcInputError & e) {
631 e << EI_InputType(string_type->
desc());
635 if (string_type->
match(value))
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()) );
652 }
catch (Input::Type::ExcWrongDefault & e) {
654 e << Type::EI_Desc(
"Wrong default value while reading an input stream:\n");
655 e << EI_KeyName(
"UNKNOWN KEY");
657 }
catch (Input::Type::ExcWrongDefaultJSON & e) {
658 e << EI_KeyName(
"UNKNOWN KEY");
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()) );
694 return storage_array;
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: ")
719 auto tmp_root_type =
static_cast<const typename T::InputType &
>(*root_type_);
720 return T( addr, tmp_root_type );
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;
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.