Flow123d  3.9.0-895a22dee
path_yaml.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 path_yaml.cc
15  * @brief
16  */
17 
18 #include "input/path_yaml.hh"
20 
21 #include "system/global_defs.h"
22 #include "system/system.hh"
23 #include "yaml-cpp/yaml.h"
24 
25 
26 namespace Input {
27 using namespace std;
28 
29 
30 PathYAML::PathYAML(istream &in)
31 : PathBase()
32 {
33  nodes_.push_back( YAML::Load( in ) );
34 
35  json_type_names.push_back("YAML map");
36  json_type_names.push_back("YAML sequence");
37  json_type_names.push_back("YAML string");
38  json_type_names.push_back("YAML bool");
39  json_type_names.push_back("YAML int");
40  json_type_names.push_back("YAML real");
41  json_type_names.push_back("YAML null");
42  json_type_names.push_back("other scalar type");
43  json_type_names.push_back("undefined type");
44 }
45 
47 {
48  this->go_to_root();
49 }
50 
51 
52 bool PathYAML::down(unsigned int index) {
53  ASSERT(head().IsSequence()).error("Head node must be of type Array.");
54 
55  if ( index >= head().size() ) return false;
56  path_.push_back( make_pair( index, string("") ) );
57  nodes_.push_back( head()[index] );
58 
59  return true;
60 }
61 
62 
63 bool PathYAML::down(const string& key, int index) {
64  ASSERT(head().IsMap()).error("Head node must be of type Record.");
65 
66  // This does the check of uniqueness of keys.
67  std::set<std::string> key_list;
68  get_record_key_set(key_list);
69 
70  if ( head()[key] ) {
71  path_.push_back( make_pair( index, key) );
72  nodes_.push_back( head()[key] );
73  } else {
74  return false;
75  }
76  return true;
77 }
78 
79 
80 void PathYAML::up() {
81  if (path_.size() > 1) {
82  path_.pop_back();
83  nodes_.pop_back();
84  }
85 }
86 
87 
88 bool PathYAML::is_null_type() const {
89  return head().IsNull();
90 }
91 
92 
94  if (head().IsScalar()) {
95  try {
96  return head().as<bool>();
97  } catch (YAML::Exception) {
98  THROW( ReaderInternalBase::ExcInputError() );
99  }
100  } else {
101  THROW( ReaderInternalBase::ExcInputError() );
102  }
103  return false;
104 }
105 
106 
107 std::int64_t PathYAML::get_int_value() const {
108  if (head().IsScalar()) {
109  try {
110  return head().as<std::int64_t>();
111  } catch (YAML::Exception) {
112  THROW( ReaderInternalBase::ExcInputError() );
113  }
114  } else {
115  THROW( ReaderInternalBase::ExcInputError() );
116  }
117  return 0;
118 }
119 
120 
122  if (head().IsScalar()) {
123  try {
124  return head().as<double>();
125  } catch (YAML::Exception) {
126  THROW( ReaderInternalBase::ExcInputError() );
127  }
128  } else {
129  THROW( ReaderInternalBase::ExcInputError() );
130  }
131  return 0.0;
132 }
133 
134 
135 std::string PathYAML::get_string_value() const {
136  if (head().IsScalar()) {
137  try {
138  return head().as<std::string>();
139  } catch (YAML::Exception) {
140  THROW( ReaderInternalBase::ExcInputError() );
141  }
142  } else {
143  THROW( ReaderInternalBase::ExcInputError() );
144  }
145  return "";
146 }
147 
148 
149 unsigned int PathYAML::get_node_type_index() const {
150  switch (head().Type()) {
151  case YAML::NodeType::Null: return ValueTypes::null_type;
152  case YAML::NodeType::Scalar: return ValueTypes::scalar_type;
153  case YAML::NodeType::Sequence: return ValueTypes::array_type;
154  case YAML::NodeType::Map: return ValueTypes::obj_type;
155  default: return ValueTypes::undef_type;
156  }
157 }
158 
159 
160 bool PathYAML::get_record_key_set(std::set<std::string> &keys_list) const {
161  if ( head().IsMap() ) {
162  for (YAML::const_iterator it=head().begin(); it!=head().end(); ++it) {
163  std::string key = it->first.as<std::string>();
164  // returns pair<iterator,true> if inserted, it expects uniqueness
165  bool key_inserted = keys_list.insert( key ).second;
166  if(! key_inserted)
167  THROW( ReaderInternalBase::ExcDuplicitTag()
168  << ReaderInternalBase::EI_Tag(key)
169  << EI_ErrorAddress(this->as_string())
170  << EI_Address(this->as_string()));
171  }
172  return true;
173  }
174 
175  return false;
176 }
177 
178 
180  if (head().IsSequence()) {
181  return head().size();
182  }
183  return -1;
184 }
185 
186 
188  return head().IsMap();
189 }
190 
191 
193  return head().IsSequence();
194 }
195 
196 
198  return new PathYAML(*this);
199 }
200 
201 
203 {
204  return NULL;
205 }
206 
207 
208 
209 std::string PathYAML::get_record_tag() const {
210  std::string tag = head().Tag();
211  if ( (tag == "?") || (tag.size() == 0) ) {
212  return "";
213  } else {
214  return tag.erase(0, 1); // tag starts with '!' char
215  }
216 }
217 
218 
219 
221  if ( head().IsNull() ) {
222  // null value indicates empty record ...
223  return true;
224  } else if ( head().IsScalar() ) {
225  try {
226  // ... or empty string indicates empty record too
227  return (head().as<std::string>() == "");
228  } catch (YAML::Exception) {
229  // other cases don't have to lead to an error
230  }
231 
232  }
233  return false;
234 }
235 
236 
237 
238 std::ostream& operator<<(std::ostream& stream, const PathYAML& path) {
239  path.output(stream);
240  return stream;
241 }
242 
243 
244 } // namespace Input
Input::PathYAML::get_node_type_index
unsigned int get_node_type_index() const override
Implements PathBase::get_node_type_index.
Definition: path_yaml.cc:149
Input::PathYAML::get_int_value
std::int64_t get_int_value() const override
Implements PathBase::get_int_value.
Definition: path_yaml.cc:107
Input
Abstract linear system class.
Definition: balance.hh:40
ASSERT
#define ASSERT(expr)
Definition: asserts.hh:351
Input::operator<<
std::ostream & operator<<(std::ostream &stream, const Address &address)
Definition: accessors.hh:252
Input::PathYAML::is_null_type
bool is_null_type() const override
Implements PathBase::is_null_type.
Definition: path_yaml.cc:88
Input::PathYAML::get_array_size
int get_array_size() const override
Implements PathBase::get_array_size.
Definition: path_yaml.cc:179
Input::PathBase::json_type_names
std::vector< std::string > json_type_names
Names of all possible node types in parsed input tree.
Definition: path_base.hh:175
Input::PathYAML::find_ref_node
PathBase * find_ref_node() override
Implements reading of reference keys, and check of cyclic references.
Definition: path_yaml.cc:202
Input::PathBase
Base abstract class used by ReaderToStorage class to iterate over the input tree.
Definition: path_base.hh:41
Input::undef_type
@ undef_type
Definition: reader_to_storage.hh:72
Input::scalar_type
@ scalar_type
Definition: reader_to_storage.hh:72
THROW
#define THROW(whole_exception_expr)
Wrapper for throw. Saves the throwing point.
Definition: exceptions.hh:53
system.hh
reader_internal_base.hh
Input::PathBase::as_string
std::string as_string() const
Returns string address of current position.
Definition: path_base.cc:48
Input::PathYAML::head
const Node & head() const
Pointer to YAML Value object at current path.
Definition: path_yaml.hh:111
path_yaml.hh
Input::PathYAML
Class used by ReaderToStorage class to iterate over the YAML tree provided by yaml-cpp library.
Definition: path_yaml.hh:47
Input::PathYAML::get_record_key_set
bool get_record_key_set(std::set< std::string > &) const override
Implements PathBase::get_record_key_set.
Definition: path_yaml.cc:160
Input::PathBase::go_to_root
void go_to_root()
Move to root node.
Definition: path_base.cc:56
Input::PathYAML::is_array_type
bool is_array_type() const override
Implements PathBase::is_array_type.
Definition: path_yaml.cc:192
json_spirit::null_type
@ null_type
Definition: json_spirit_value.h:32
Input::PathBase::path_
std::vector< std::pair< int, std::string > > path_
One level of the path_ is either index (nonnegative int) in array or string key in a json object.
Definition: path_base.hh:166
Input::PathYAML::PathYAML
PathYAML(std::istream &in)
Constructor.
Definition: path_yaml.cc:30
json_spirit::array_type
@ array_type
Definition: json_spirit_value.h:32
Input::PathYAML::~PathYAML
~PathYAML() override
Destructor.
Definition: path_yaml.cc:46
Input::Type
Definition: balance.hh:41
Input::PathYAML::nodes_
std::vector< Node > nodes_
Definition: path_yaml.hh:115
Input::PathYAML::is_effectively_null
bool is_effectively_null() const override
Implements PathBase::is_effectively_null.
Definition: path_yaml.cc:220
Input::PathYAML::is_record_type
bool is_record_type() const override
Implements PathBase::is_record_type.
Definition: path_yaml.cc:187
Input::PathBase::output
void output(std::ostream &stream) const
Output to the given stream.
Definition: path_base.cc:31
Input::PathYAML::clone
PathYAML * clone() const override
Implements PathBase::clone.
Definition: path_yaml.cc:197
global_defs.h
Global macros to enhance readability and debugging, general constants.
Input::PathYAML::get_double_value
double get_double_value() const override
Implements PathBase::get_double_value.
Definition: path_yaml.cc:121
std
Definition: doxy_dummy_defs.hh:5
Input::PathYAML::get_bool_value
bool get_bool_value() const override
Implements PathBase::get_bool_value.
Definition: path_yaml.cc:93
Input::PathYAML::up
void up() override
Return one level up in the hierarchy.
Definition: path_yaml.cc:80
Input::PathYAML::down
bool down(unsigned int index) override
Dive into yaml-cpp hierarchy.
Definition: path_yaml.cc:52
Input::PathYAML::get_string_value
std::string get_string_value() const override
Implements PathBase::get_string_value.
Definition: path_yaml.cc:135
Input::PathYAML::get_record_tag
std::string get_record_tag() const override
Implements PathBase::get_record_tag.
Definition: path_yaml.cc:209
json_spirit::obj_type
@ obj_type
Definition: json_spirit_value.h:32