9 #ifndef JSON_PACK_BASE_H 10 #define JSON_PACK_BASE_H 11 #include "classdesc.h" 12 #include <json_spirit.h> 20 class json_pack_error :
public exception
22 static const int maxchars=200;
23 char errstring[maxchars];
25 json_pack_error(
const char *fmt,...)
29 vsnprintf(errstring,maxchars,fmt,args);
32 virtual ~json_pack_error() throw() {}
33 virtual const char* what()
const throw() {
return errstring;}
36 struct json_object_not_found:
public json_pack_error
38 json_object_not_found(
const string& name):
39 json_pack_error(
"json object %s not found", name.c_str()) {}
43 class json_pack_t:
public json_spirit::mValue
47 bool throw_on_not_found;
48 json_pack_t(): json_spirit::mValue(json_spirit::mObject()),
49 throw_on_error(false) {}
50 json_pack_t(
const json_spirit::mValue& x):
51 json_spirit::mValue(x), throw_on_error(false), throw_on_not_found(false) {}
55 typedef json_pack_t json_unpack_t;
58 template <
class T>
void json_pack(json_pack_t& o,
const string& d, T& a);
60 template <
class T>
void json_pack(json_pack_t& o,
const string& d,
const T& a)
63 template <
class T>
void json_unpack(json_unpack_t& o,
const string& d, T& a);
65 template <
class T> json_pack_t& operator<<(json_pack_t& j,
const T& a)
68 template <
class T>
const json_unpack_t& operator>>(
const json_unpack_t& j, T& a)
69 {json_unpack(const_cast<json_unpack_t&>(j),
"",a);
return j;}
72 inline json_spirit::mValue&
73 json_find(json_spirit::mValue& x, std::string name)
75 if (name.size()==0)
return x;
76 if (name[0]==
'.') name.erase(0,1);
77 std::string::size_type p=name.find(
'.');
78 if (x.type()==json_spirit::obj_type)
80 json_spirit::mObject& xo=x.get_obj();
81 json_spirit::mObject::iterator i=xo.find(name.substr(0,p));
83 throw json_object_not_found(name.substr(0,p));
84 else if (p==std::string::npos)
87 return json_find(i->second,name.substr(p,std::string::npos));
90 throw json_pack_error(
"%s is not a json object",name.c_str());
94 template <
class T> json_spirit::mValue valueof(T a)
95 {
return json_spirit::mValue(a);}
96 template <
class T> T getValue(
const json_spirit::mValue& x)
97 {
return x.get_value<T>();}
99 inline json_spirit::mValue valueof(
unsigned char a)
100 {
return json_spirit::mValue(
int(a));}
101 template <>
inline unsigned char getValue(
const json_spirit::mValue& x)
102 {
return x.get_value<
int>();}
104 inline json_spirit::mValue valueof(
signed char a)
105 {
return json_spirit::mValue(
int(a));}
106 template <>
inline signed char getValue(
const json_spirit::mValue& x)
107 {
return x.get_value<
int>();}
109 inline json_spirit::mValue valueof(
char a)
110 {
return json_spirit::mValue(
int(a));}
111 template <>
inline char getValue(
const json_spirit::mValue& x)
112 {
return x.get_value<
int>();}
114 inline json_spirit::mValue valueof(
unsigned short a)
115 {
return json_spirit::mValue(
int(a));}
116 template <>
inline unsigned short getValue(
const json_spirit::mValue& x)
117 {
return x.get_value<
int>();}
119 inline json_spirit::mValue valueof(
signed short a)
120 {
return json_spirit::mValue(
int(a));}
121 template <>
inline signed short getValue(
const json_spirit::mValue& x)
122 {
return x.get_value<
int>();}
124 inline json_spirit::mValue valueof(
unsigned int a)
125 {
return json_spirit::mValue(boost::uint64_t(a));}
126 template <>
inline unsigned getValue(
const json_spirit::mValue& x)
127 {
return x.get_value<boost::uint64_t>();}
129 inline json_spirit::mValue valueof(
unsigned long a)
130 {
return json_spirit::mValue(boost::uint64_t(a));}
131 template <>
inline unsigned long getValue(
const json_spirit::mValue& x)
132 {
return x.get_value<boost::uint64_t>();}
134 inline json_spirit::mValue valueof(
long a)
135 {
return json_spirit::mValue(boost::int64_t(a));}
136 template <>
inline long getValue(
const json_spirit::mValue& x)
137 {
return x.get_value<boost::int64_t>();}
140 inline json_spirit::mValue valueof(
unsigned long long a)
141 {
return json_spirit::mValue(boost::uint64_t(a));}
142 template <>
inline unsigned long long getValue(
const json_spirit::mValue& x)
143 {
return x.get_value<boost::uint64_t>();}
145 inline json_spirit::mValue valueof(
long long a)
146 {
return json_spirit::mValue(boost::int64_t(a));}
147 template <>
inline long long getValue(
const json_spirit::mValue& x)
148 {
return x.get_value<boost::int64_t>();}
151 inline json_spirit::mValue valueof(
float a)
152 {
return json_spirit::mValue(
double(a));}
153 template <>
inline float getValue(
const json_spirit::mValue& x)
154 {
return x.get_value<
double>();}
157 template <
class T>
typename 158 enable_if<Or<is_fundamental<T>,is_string<T> >,
void>::T
159 json_packp(json_unpack_t& o,
const string& d,
const T& a, dummy<0> dum=0)
161 using namespace json_spirit;
168 json_spirit::mValue& parent=
json_find(o,head(d));
169 if (parent.type()==obj_type)
170 parent.get_obj()[tail(d)]=valueof(a);
172 throw json_pack_error(
"cannot add to a basic type");
174 catch (
const json_object_not_found&)
177 if (o.throw_on_not_found)
throw;
179 catch (
const json_pack_error&)
182 if (o.throw_on_error)
throw;
188 template <
class T>
typename 189 enable_if<Or<is_fundamental<T>,is_string<T> >,
void>::T
190 json_unpackp(json_unpack_t& o,
string d, T& a, dummy<0> dum=0)
196 catch (
const json_pack_error&)
199 if (o.throw_on_error)
throw;
203 template <
class T>
void json_pack_isarray
204 (json_spirit::mValue& jval,
const T& val, std::vector<size_t> dims)
214 size_t s=dims.back();
215 jval=json_spirit::mArray(s);
218 for (
size_t i=0; i<dims.size(); ++i) stride*=dims[i];
219 for (
size_t i=0; i<s; ++i)
220 json_pack_isarray(jval.get_array()[i],(&val)[i*stride], dims);
226 void json_pack(json_pack_t& o,
const string& d, is_array ia,
const T& a,
227 int ndims,
size_t ncopies,...)
230 va_start(ap,ncopies);
231 std::vector<size_t> dims(ndims);
232 dims[ndims-1]=ncopies;
233 for (
int i=ndims-2; i>=0; --i) dims[i]=va_arg(ap,
size_t);
237 json_spirit::mValue& parent=
json_find(o,head(d));
238 if (parent.type()!=json_spirit::obj_type)
239 throw json_pack_error(
"attempt to pack an array member into a non-object");
241 json_pack_isarray(parent.get_obj()[tail(d)],a,dims);
243 catch (json_pack_error&)
246 if (o.throw_on_error)
throw;
250 template <
class T>
void json_unpack_isarray
251 (
const json_spirit::mValue& jval, T& val, std::vector<size_t> dims)
255 json_unpack_t j(jval);
256 json_unpack(j,
"",val);
260 size_t s=dims.back();
263 for (
size_t i=0; i<dims.size(); ++i) stride*=dims[i];
264 for (
size_t i=0; i<s; ++i)
265 json_unpack_isarray(jval.get_array()[i],(&val)[i*stride], dims);
270 void json_unpack(json_unpack_t& o,
const string& d, is_array ia, T& a,
271 int ndims,
size_t ncopies,...)
274 va_start(ap,ncopies);
275 std::vector<size_t> dims(ndims);
276 dims[ndims-1]=ncopies;
277 for (
int i=ndims-2; i>=0; --i) dims[i]=va_arg(ap,
size_t);
281 const json_spirit::mValue& v=
json_find(o,d);
282 if (v.type()!=json_spirit::array_type)
283 throw json_pack_error
284 (
"attempt to unpack an array member from a non-object");
286 json_unpack_isarray(v,a,dims);
288 catch (json_pack_error&)
291 if (o.throw_on_error)
throw;
301 template <
class T>
void json_pack(json_pack_t& x,
const string& d,
304 string tmp(static_cast<string>(arg));
309 template <
class T>
void json_unpack(json_unpack_t& x,
const string& d,
313 json_unpack(x,d,tmp);
315 int (*isspace)(int)=std::isspace;
316 std::string::iterator end=std::remove_if(tmp.begin(),tmp.end(),isspace);
317 arg=tmp.substr(0,end-tmp.begin());
321 template <
class T>
typename 322 enable_if<is_sequence<T>,
void>::T
323 json_unpackp(json_unpack_t& o,
const string& d, T& a, dummy<1> dum=0)
327 const json_spirit::mValue& val=
json_find(o,d);
328 if (val.type()!=json_spirit::array_type)
329 throw json_pack_error(
"%s is not an array",d.c_str());
332 const json_spirit::mArray& arr=val.get_array();
334 for (
size_t i=0; i<arr.size(); ++i)
336 typename T::value_type v;
337 json_unpack_t j(arr[i]);
343 catch (json_pack_error&)
345 if (o.throw_on_error)
throw;
349 template <
class T1,
class T2>
350 void json_pack(json_pack_t& o,
const string& d, std::pair<T1,T2>& a)
356 template <
class T1,
class T2>
357 void json_unpackp(json_unpack_t& o,
const string& d, std::pair<T1,T2>& a)
359 json_unpack(o,d+
".first",a.first);
360 json_unpack(o,d+
".second",a.second);
363 template <
class T>
typename 364 enable_if<Or<is_sequence<T>,is_associative_container<T> >,
void>::T
365 json_packp(json_pack_t& o,
const string& d,
const T& a, dummy<1> dum=0)
369 json_spirit::mValue& parent=
json_find(o,head(d));
370 if (parent.type()!=json_spirit::obj_type)
371 throw json_pack_error(
"attempt to pack an array member into a non-object");
374 json_spirit::mValue* v;
378 v=&parent.get_obj()[tail(d)];
380 json_spirit::mArray& arr=
381 (*v=json_spirit::mArray(a.size())).get_array();
382 typename T::const_iterator i=a.begin();
383 for (
size_t k=0; i!=a.end(); ++i, ++k)
391 catch (json_pack_error&)
393 if (o.throw_on_error)
throw;
397 template <
class T>
typename 398 enable_if<is_associative_container<T>,
void>::T
399 json_unpackp(json_unpack_t& o,
const string& d, T& a, dummy<2> dum=0)
403 const json_spirit::mValue& val=
json_find(o,d);
404 if (val.type()!=json_spirit::array_type)
405 throw json_pack_error(
"%s is not an array",d.c_str());
408 const json_spirit::mArray& arr=val.get_array();
410 for (
size_t i=0; i<arr.size(); ++i)
412 typename NonConstKeyValueType<typename T::value_type>::T v;
413 json_unpack_t j(arr[i]);
419 catch (json_pack_error&)
421 if (o.throw_on_error)
throw;
428 template <
class C,
class T>
429 void json_pack(json_pack_t& targ,
const string& desc, C& c, T arg) {}
431 template <
class C,
class T>
432 void json_unpack(json_unpack_t& targ,
const string& desc, C& c, T arg) {}
438 void json_pack(json_pack_t& targ,
const string& desc, is_const_static i, T arg)
442 void json_unpack(json_unpack_t& targ,
const string& desc, is_const_static i, T arg)
446 template <
class T,
class U>
447 void json_pack(json_pack_t&,
const string&, is_const_static,
const T&, U) {}
450 template <
class T,
class U>
451 void json_unpack(json_unpack_t&,
const string&, is_const_static,
const T&, U) {}
454 void json_unpack(json_unpack_t& targ,
const string& desc,
const T& arg) {}
457 void json_pack(json_pack_t& targ,
const string& desc, Exclude<T>& arg) {}
460 void json_unpack(json_unpack_t& targ,
const string& desc, Exclude<T>& arg) {}
463 template <
class T>
string json(
const T& x)
469 template <
class T>
void json(T& x,
const string& s)
477 void json_pack_onbase(json_pack_t& x,
const string& d,T& a)
481 void json_unpack_onbase(json_unpack_t& x,
const string& d,T& a)
482 {json_unpack(x,d+basename<T>(),a);}
489 template <
class T>
struct access_json_pack;
490 template <
class T>
struct access_json_unpack;
493 using classdesc::json_pack_onbase;
494 using classdesc::json_unpack_onbase;
497 using classdesc::json_unpack;
void json_pack(json_pack_t &o, const string &d, T &a)
forward declare generic json operations
Definition: json_pack_epilogue.h:53
string json(const T &x)
produce json string equivalent of object x
Definition: json_pack_base.h:463
Contains definitions related to classdesc functionality.
Definition: arrays.h:2514
Contains access_* structs, and nothing else. These structs are used to gain access to private members...
Definition: accessor.h:55
json_spirit::mValue & json_find(json_spirit::mValue &x, std::string name)
find an object named by name within the json object x
Definition: json_pack_base.h:73