Flow123d  release_2.2.0-914-gf1a3a4f
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 #include "input/reader_internal.hh"
29 #include <stddef.h> // for NULL
30 #include <boost/exception/detail/error_info_impl.hpp> // for error_info
31 #include <ostream> // for operator<<
32 #include <set> // for set, _Rb_tree_...
33 #include <typeinfo> // for type_info
34 #include <utility> // for pair
35 #include <vector> // for vector
36 #include "system/asserts.hh" // for Assert, ASSERT
37 #include "system/file_path.hh" // for FilePath, File...
38 #include "system/logger.hh" // for operator<<
39 
40 
41 namespace Input {
42 using namespace std;
43 using namespace internal;
44 
45 
46 
47 /********************************************
48  * Implementation of public part of ReaderToStorage
49  */
50 
52 : storage_(nullptr),
53  root_type_(nullptr)
54 {}
55 
56 
57 
60 {
61  std::string fname = in_file;
62  std::string extension = fname.substr(fname.find_last_of(".") + 1);
64  if (extension == "con") {
65  format = FileFormat::format_JSON;
66  } else if (extension == "yaml") {
67  format = FileFormat::format_YAML;
68  } else {
69  THROW(ExcInputMessage() << EI_Message("Invalid extension of file " + fname + ".\nMust be 'con' or 'yaml'."));
70  }
71 
72  std::ifstream in;
73  in_file.open_stream(in);
74 
75  // finish of root_type ensures finish of whole IST
76  root_type.finish();
77 
78  read_stream(in, root_type, format);
79 }
80 
81 
82 
85 {
86  // finish of root_type ensures finish of whole IST
87  root_type.finish();
88 
89  try {
90  istringstream is(str);
91  read_stream(is, root_type, format);
92  } catch (ReaderInternalBase::ExcNotJSONFormat &e) {
93  e << ReaderInternalBase::EI_File("STRING: "+str); throw;
94  }
95 }
96 
97 
98 
100 {
101  return storage_;
102 }
103 
104 
105 
106 void ReaderToStorage::read_stream(istream &in, const Type::TypeBase &root_type, FileFormat format)
107 {
108  ASSERT(storage_==nullptr).error();
109 
110  PathBase * root_path;
111  if (format == FileFormat::format_JSON) {
112  root_path = new PathJSON(in);
113  } else {
114  root_path = new PathYAML(in);
115  }
116 
117  // guarantee to delete root_path on function return even on exception
118  std::unique_ptr<PathBase> root_path_ptr(root_path);
119 
120  root_type_ = &root_type;
121  try {
122  ReaderInternal ri;
123  storage_ = ri.read_storage(*root_path_ptr, root_type_);
124  } catch (ReaderInternalBase::ExcInputError &e) {
125  if (format == FileFormat::format_JSON) {
126  e << ReaderInternalBase::EI_Format("JSON");
127  } else {
128  e << ReaderInternalBase::EI_Format("YAML");
129  }
130  throw;
131  }
132 
133  ASSERT_PTR(storage_).error();
134 }
135 
136 
137 
138 
139 
140 
141 /********************************************88
142  * Implementation
143  */
144 
145 template <class T>
147 {
148  ASSERT_PTR(storage_).error();
149 
150  Address addr(storage_, root_type_);
151  // try to create an iterator just to check type
152  Iterator<T>( *root_type_, addr, 0);
153 
154  auto tmp_root_type = static_cast<const typename T::InputType &>(*root_type_);
155  return T( addr, tmp_root_type );
156 }
157 
158 
159 template ::Input::Record ReaderToStorage::get_root_interface<::Input::Record>() const;
160 template ::Input::Array ReaderToStorage::get_root_interface<::Input::Array>() const;
161 template ::Input::AbstractRecord ReaderToStorage::get_root_interface<::Input::AbstractRecord>() const;
162 template ::Input::Tuple ReaderToStorage::get_root_interface<::Input::Tuple>() const;
163 //template ReaderToStorage::get_root_interface<::Input::>()->::Input::AbstractRecord const;
164 
165 
166 } // namespace Input
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:99
Base class for nodes of a data storage tree.
Definition: storage.hh:68
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:47
Class used by ReaderToStorage class to iterate over the JSON tree provided by json_spirit library...
Definition: path_json.hh:46
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:217
Base abstract class used by ReaderToStorage class to iterate over the input tree. ...
Definition: path_base.hh:41
Abstract linear system class.
Definition: equation.hh:37
std::string format(CStringRef format_str, ArgList args)
Definition: format.h:3141
Definitions of ASSERTS.
#define ASSERT(expr)
Allow use shorter versions of macro names if these names is not used with external library...
Definition: asserts.hh:346
const Type::TypeBase * root_type_
Root of the declaration tree of the data in the storage.
StorageBase * get_storage()
Getter for root of the storage tree.
Creates storage of IST defined in JSON or YAML file.
void open_stream(Stream &stream) const
Definition: file_path.cc:211
T get_root_interface() const
Returns the root accessor.
ReaderToStorage()
Default constructor.
Dedicated class for storing path to input and output files.
Definition: file_path.hh:54
#define ASSERT_PTR(ptr)
Definition of assert macro checking non-null pointer (PTR)
Definition: asserts.hh:335
#define THROW(whole_exception_expr)
Wrapper for throw. Saves the throwing point.
Definition: exceptions.hh:53
StorageBase * read_storage(PathBase &p, const Type::TypeBase *type)
Create storage of given type.
StorageBase * storage_
Storage of the read and checked input data.