Extension: Json and NetCDF utilities
#include "dg/file/file.h" (includes both Json and NetCDF utilities)
json_utilities.h
Go to the documentation of this file.
1#pragma once
2
3#include <iostream>
4#include <fstream>
5#include <string>
6#include <sstream>
7#include <stdexcept> //std::runtime_error
8
9#include "json/json.h"
15//Note that the json utilities are separate from netcdf utilities because
16//of the different library dependencies that they incur
17namespace dg
18{
19namespace file
20{
30enum class error{
31 is_throw,
34};
35
37enum class comments{
38 are_kept,
41};
42
90{
93 WrappedJsonValue() : m_js(0), m_mode( error::is_throw){}
96 WrappedJsonValue( error mode): m_js(0), m_mode( mode) {}
99 WrappedJsonValue(Json::Value js): m_js(js), m_mode( error::is_throw) {}
103 WrappedJsonValue(Json::Value js, error mode): m_js(js), m_mode( mode) {}
106 void set_mode( error new_mode){
107 m_mode = new_mode;
108 }
110 const Json::Value& asJson( ) const{ return m_js;}
112 Json::Value& asJson( ) { return m_js;}
113
119 std::string access_string() const {return m_access_str;}
120
121 // //////////Members imitating the original Json::Value///////////////
123 WrappedJsonValue operator[](std::string key) const{
124 return get( key, Json::ValueType::objectValue, "empty object ");
125 }
127 WrappedJsonValue get( std::string key, const Json::Value& value) const{
128 std::stringstream default_str;
129 default_str << "value "<<value;
130 return get( key, value, default_str.str());
131 }
133 WrappedJsonValue operator[]( unsigned idx) const{
134 return get( idx, Json::ValueType::objectValue, "empty array");
135 }
137 WrappedJsonValue get( unsigned idx, const Json::Value& value) const{
138 std::stringstream default_str;
139 default_str << "value "<<value;
140 return get( idx, value, default_str.str());
141 }
143 unsigned size() const{
144 return m_js.size();
145 }
147 double asDouble( double value = 0) const{
148 if( m_js.isDouble())
149 return m_js.asDouble();
150 return type_error<double>( value, "a Double");
151 }
153 unsigned asUInt( unsigned value = 0) const{
154 if( m_js.isUInt())
155 return m_js.asUInt();
156 return type_error<unsigned>( value, "an Unsigned");
157 }
159 int asInt( int value = 0) const{
160 if( m_js.isInt())
161 return m_js.asInt();
162 return type_error<int>( value, "an Int");
163 }
165 bool asBool( bool value = false) const{
166 if( m_js.isBool())
167 return m_js.asBool();
168 return type_error<bool>( value, "a Bool");
169 }
171 std::string asString( std::string value = "") const{
172 //return m_js["hhaha"].asString(); //does not throw
173 if( m_js.isString())
174 return m_js.asString();
175 return type_error<std::string>( value, "a String");
176 }
177 private:
178 WrappedJsonValue(Json::Value js, error mode, std::string access):m_js(js), m_mode( mode), m_access_str(access) {}
179 WrappedJsonValue get( std::string key, const Json::Value& value, std::string default_str) const
180 {
181 std::string access = m_access_str + "\""+key+"\": ";
182 std::stringstream message;
183 if( !m_js.isObject( ) || !m_js.isMember(key))
184 {
185 message <<"*** Key error: "<<access<<" not found.";
186 raise_error( message.str(), default_str);
187 return WrappedJsonValue( value, m_mode, access);
188 }
189 return WrappedJsonValue(m_js[key], m_mode, access);
190 }
191 WrappedJsonValue get( unsigned idx, const Json::Value& value, std::string default_str) const
192 {
193 std::string access = m_access_str + "["+std::to_string(idx)+"] ";
194 if( !m_js.isArray() || !m_js.isValidIndex(idx))
195 {
196 std::stringstream message;
197 //if( !m_js.isArray())
198 // message <<"*** Key error: "<<m_access_str<<" is not an Array.";
199 //else
200 if( m_access_str.empty())
201 message <<"*** Index error: Index "<<idx<<" not present.";
202 else
203 message <<"*** Index error: Index "<<idx<<" not present in "<<m_access_str<<".";
204 raise_error( message.str(), default_str);
205 return WrappedJsonValue( value, m_mode, access);
206 }
207 return WrappedJsonValue(m_js[idx], m_mode, access);
208 }
209 template<class T>
210 T type_error( T value, std::string type) const
211 {
212 std::stringstream message, default_str;
213 default_str << "value "<<value;
214 message <<"*** Type error: "<<m_access_str<<" "<<m_js<<" is not "<<type<<".";
215 raise_error( message.str(), default_str.str());
216 return value;
217 }
218 void raise_error( std::string message, std::string default_str) const
219 {
220 if( error::is_throw == m_mode)
221 throw std::runtime_error( message);
222 else if ( error::is_warning == m_mode)
223 std::cerr <<"WARNING "<< message<<" Using default "<<default_str<<"\n";
224 else
225 ;
226 }
227 Json::Value m_js;
228 error m_mode;
229 std::string m_access_str = "";
230};
231
244static inline void file2Json(std::string filename, Json::Value& js, enum comments comm = file::comments::are_discarded, enum error err = file::error::is_throw)
245{
246 Json::CharReaderBuilder parser;
247 if( comments::are_forbidden == comm )
248 Json::CharReaderBuilder::strictMode( &parser.settings_);
249 else if( comments::are_discarded == comm )
250 {
251 Json::CharReaderBuilder::strictMode( &parser.settings_);
252 // workaround for a linker bug in jsoncpp from package manager
253 Json::Value js_true (true);
254 Json::Value js_false (false);
255 parser.settings_["allowComments"].swap( js_true);
256 parser.settings_["collectComments"].swap(js_false);
257 }
258 else
259 Json::CharReaderBuilder::setDefaults( &parser.settings_);
260
261 std::ifstream isI( filename);
262 if( !isI.good())
263 {
264 std::string message = "\nAn error occured while parsing "+filename+"\n";
265 message += "*** File does not exist! *** \n\n";
266 if( err == error::is_throw)
267 throw std::runtime_error( message);
268 else if (err == error::is_warning)
269 std::cerr << "WARNING: "<<message<<std::endl;
270 else
271 ;
272 return;
273 }
274 std::string errs;
275 if( !parseFromStream( parser, isI, &js, &errs) )
276 {
277 std::string message = "An error occured while parsing "+filename+"\n"+errs;
278 if( err == error::is_throw)
279 throw std::runtime_error( message);
280 else if (err == error::is_warning)
281 std::cerr << "WARNING: "<<message<<std::endl;
282 else
283 ;
284 return;
285 }
286}
301static inline void string2Json(std::string input, Json::Value& js, enum comments comm = file::comments::are_discarded, enum error err = file::error::is_throw)
302{
303 Json::CharReaderBuilder parser;
304 if( comments::are_forbidden == comm )
305 Json::CharReaderBuilder::strictMode( &parser.settings_);
306 else if( comments::are_discarded == comm )
307 {
308 Json::CharReaderBuilder::strictMode( &parser.settings_);
309 parser.settings_["allowComments"] = true;
310 parser.settings_["collectComments"] = false;
311 }
312 else
313 Json::CharReaderBuilder::setDefaults( &parser.settings_);
314
315 std::string errs;
316 std::stringstream ss(input);
317 if( !parseFromStream( parser, ss, &js, &errs) )
318 {
319 if( err == error::is_throw)
320 throw std::runtime_error( errs);
321 else if (err == error::is_warning)
322 std::cerr << "WARNING: "<<errs<<std::endl;
323 else
324 ;
325 return;
326 }
327}
328
330}//namespace file
331}//namespace dg
static void string2Json(std::string input, Json::Value &js, enum comments comm=file::comments::are_discarded, enum error err=file::error::is_throw)
Convenience wrapper to parse a string into a Json::Value.
Definition: json_utilities.h:301
static void file2Json(std::string filename, Json::Value &js, enum comments comm=file::comments::are_discarded, enum error err=file::error::is_throw)
Convenience wrapper to open a file and parse it into a Json::Value.
Definition: json_utilities.h:244
error
Switch between how to handle errors in a Json utitlity functions.
Definition: json_utilities.h:30
comments
Switch how comments are treated in a json string or file.
Definition: json_utilities.h:37
@ is_warning
Handle the error by writing a warning to std::cerr.
@ is_silent
Ignore the error and silently continue execution.
@ is_throw
throw an error
@ are_discarded
Allow comments but discard them in the Json value.
@ are_kept
Keep comments in the Json value.
@ are_forbidden
Treat comments as invalid Json.
Wrapped Access to Json values with error handling.
Definition: json_utilities.h:90
std::string asString(std::string value="") const
Wrap the corresponding Json::Value function with error handling.
Definition: json_utilities.h:171
WrappedJsonValue()
Default constructor By default the error mode is error::is_throw.
Definition: json_utilities.h:93
const Json::Value & asJson() const
Read access to the raw Json value.
Definition: json_utilities.h:110
WrappedJsonValue get(std::string key, const Json::Value &value) const
Wrap the corresponding Json::Value function with error handling.
Definition: json_utilities.h:127
WrappedJsonValue get(unsigned idx, const Json::Value &value) const
Wrap the corresponding Json::Value function with error handling.
Definition: json_utilities.h:137
WrappedJsonValue operator[](unsigned idx) const
Wrap the corresponding Json::Value function with error handling.
Definition: json_utilities.h:133
bool asBool(bool value=false) const
Wrap the corresponding Json::Value function with error handling.
Definition: json_utilities.h:165
WrappedJsonValue(Json::Value js)
By default the error mode is error::is_throw.
Definition: json_utilities.h:99
unsigned asUInt(unsigned value=0) const
Wrap the corresponding Json::Value function with error handling.
Definition: json_utilities.h:153
void set_mode(error new_mode)
Change the error mode.
Definition: json_utilities.h:106
double asDouble(double value=0) const
Wrap the corresponding Json::Value function with error handling.
Definition: json_utilities.h:147
WrappedJsonValue(error mode)
Construct with error mode.
Definition: json_utilities.h:96
WrappedJsonValue(Json::Value js, error mode)
Construct with Json value and error mode.
Definition: json_utilities.h:103
std::string access_string() const
The creation history of the object.
Definition: json_utilities.h:119
WrappedJsonValue operator[](std::string key) const
Wrap the corresponding Json::Value function with error handling.
Definition: json_utilities.h:123
Json::Value & asJson()
Write access to the raw Json value (if you know what you are doing)
Definition: json_utilities.h:112
unsigned size() const
Wrap the corresponding Json::Value function with error handling.
Definition: json_utilities.h:143
int asInt(int value=0) const
Wrap the corresponding Json::Value function with error handling.
Definition: json_utilities.h:159