00001
00002
00003
00004
00005
00006
00008 #ifndef CPPCMS_JSON_H
00009 #define CPPCMS_JSON_H
00010
00011 #include <cppcms/defs.h>
00012 #include <cppcms/string_key.h>
00013 #include <booster/copy_ptr.h>
00014 #include <booster/backtrace.h>
00015 #include <vector>
00016 #include <map>
00017 #include <string>
00018 #include <iostream>
00019 #include <limits>
00020
00021 namespace cppcms {
00025 namespace json {
00026
00027
00028
00029
00030 class value;
00031
00035 struct null {};
00039 struct undefined {};
00040
00041 inline bool operator==(undefined const &,undefined const &) {return true;}
00042 inline bool operator!=(undefined const &,undefined const &) {return false;}
00043 inline bool operator==(null const &,null const &) {return true;}
00044 inline bool operator!=(null const &,null const &) {return false;}
00045
00049 typedef std::vector<value> array;
00053 typedef std::map<string_key,value> object;
00054
00055 #ifdef CPPCMS_DOXYGEN_DOCS
00056
00061 template<typename T>
00062 struct traits {
00066 static T get(value const &v);
00070 static void set(value &v,T const &in);
00071 };
00072
00073 #else
00074
00075 template<typename T>
00076 struct traits;
00077
00078 #endif
00079
00080
00084 typedef enum {
00085 is_undefined,
00086 is_null,
00087 is_boolean,
00088 is_number,
00089 is_string,
00090 is_object,
00091 is_array
00092 } json_type;
00093
00094
00095 enum {
00096 compact = 0,
00097 readable = 1
00098 };
00099
00106 class CPPCMS_API bad_value_cast : public booster::bad_cast {
00107 public:
00108 bad_value_cast();
00109 bad_value_cast(std::string const &s);
00110 bad_value_cast(std::string const &s,json_type actual);
00111 bad_value_cast(std::string const &s,json_type expected, json_type actual);
00112
00113 virtual ~bad_value_cast() throw();
00114 virtual const char* what() const throw();
00115 private:
00116 std::string msg_;
00117 };
00118
00119 class value;
00120
00124 std::istream CPPCMS_API &operator>>(std::istream &in,value &v);
00125
00129 std::ostream CPPCMS_API &operator<<(std::ostream &out,value const &v);
00130
00134 std::ostream CPPCMS_API &operator<<(std::ostream &out,json_type);
00135
00142 class CPPCMS_API value {
00143 public:
00144
00148 json_type type() const;
00149
00153 bool is_undefined() const;
00157 bool is_null() const;
00158
00162 bool const &boolean() const;
00166 double const &number() const;
00170 std::string const &str() const;
00174 json::object const &object() const;
00178 json::array const &array() const;
00179
00183 bool &boolean();
00187 double &number();
00191 std::string &str();
00195 json::object &object();
00199 json::array &array();
00200
00204 void undefined();
00208 void null();
00209
00213 void boolean(bool);
00217 void number(double );
00221 void str(std::string const &);
00225 void object(json::object const &);
00229 void array(json::array const &);
00230
00231
00235 template<typename T>
00236 T get_value() const
00237 {
00238 return traits<T>::get(*this);
00239 }
00240
00244 template<typename T>
00245 void set_value(T const &v)
00246 {
00247 traits<T>::set(*this,v);
00248 }
00249
00257 value const &find(std::string const &path) const;
00265 value const &find(char const *path) const;
00266
00274 value const &at(std::string const &path) const;
00282 value const &at(char const *path) const;
00290 value &at(std::string const &path);
00298 value &at(char const *path);
00299
00303 void at(std::string const &path,value const &v);
00307 void at(char const *path,value const &v);
00308
00309
00313 template<typename T>
00314 value(T const &v)
00315 {
00316 set_value(v);
00317 }
00318
00324 json_type type(std::string const &path) const
00325 {
00326 return find(path).type();
00327 }
00333 json_type type(char const *path) const
00334 {
00335 return find(path).type();
00336 }
00337
00341 template<typename T>
00342 void set(std::string const &path,T const &v)
00343 {
00344 at(path,value(v));
00345 }
00349 template<typename T>
00350 void set(char const *path,T const &v)
00351 {
00352 at(path,value(v));
00353 }
00354
00359 std::string get(std::string const &path,char const *def) const
00360 {
00361 value const &v=find(path);
00362 if(v.is_undefined())
00363 return def;
00364 try {
00365 return v.get_value<std::string>();
00366 }
00367 catch(std::bad_cast const &e) {
00368 return def;
00369 }
00370 }
00375 std::string get(char const *path,char const *def) const
00376 {
00377 value const &v=find(path);
00378 if(v.is_undefined())
00379 return def;
00380 try {
00381 return v.get_value<std::string>();
00382 }
00383 catch(std::bad_cast const &e) {
00384 return def;
00385 }
00386 }
00387
00392 template<typename T>
00393 T get(std::string const &path) const
00394 {
00395 return at(path).get_value<T>();
00396 }
00401 template<typename T>
00402 T get(char const *path) const
00403 {
00404 return at(path).get_value<T>();
00405 }
00406
00411 template<typename T>
00412 T get(char const *path,T const &def) const
00413 {
00414 value const &v=find(path);
00415 if(v.is_undefined())
00416 return def;
00417 try {
00418 return v.get_value<T>();
00419 }
00420 catch(std::bad_cast const &e) {
00421 return def;
00422 }
00423 }
00428 template<typename T>
00429 T get(std::string const &path,T const &def) const
00430 {
00431 value const &v=find(path);
00432 if(v.is_undefined())
00433 return def;
00434 try {
00435 return v.get_value<T>();
00436 }
00437 catch(std::bad_cast const &e) {
00438 return def;
00439 }
00440 }
00441
00449 value &operator[](std::string const &name);
00450
00457 value const &operator[](std::string const &name) const;
00458
00463 value &operator[](size_t n);
00468 value const &operator[](size_t n) const;
00469
00473 std::string save(int how=compact) const;
00477 void save(std::ostream &out,int how=compact) const;
00488 bool load(std::istream &in,bool full,int *line_number=0);
00489
00493 bool operator==(value const &other) const;
00497 bool operator!=(value const &other) const;
00498
00502 value(value const &other) :
00503 d(other.d)
00504 {
00505 }
00509 value const &operator=(value const &other)
00510 {
00511 d=other.d;
00512 return *this;
00513 }
00517 value()
00518 {
00519 }
00520
00524
00525 ~value()
00526 {
00527 }
00528
00532 void swap(value &other)
00533 {
00534 d.swap(other.d);
00535 }
00536
00537 private:
00538
00539 void write(std::ostream &out,int tabs) const;
00540 void write_value(std::ostream &out,int tabs) const;
00541
00542 struct _data;
00543 struct CPPCMS_API copyable {
00544
00545 _data *operator->() { return &*d; }
00546 _data &operator*() { return *d; }
00547 _data const *operator->() const { return &*d; }
00548 _data const &operator*() const { return *d; }
00549
00550 copyable();
00551 copyable(copyable const &r);
00552 copyable const &operator=(copyable const &r);
00553 ~copyable();
00554
00555 void swap(copyable &other)
00556 {
00557 d.swap(other.d);
00558 }
00559 private:
00560 booster::copy_ptr<_data> d;
00561 } d;
00562
00563 friend struct copyable;
00564 };
00565
00566
00567
00569
00570 template<typename T1,typename T2>
00571 struct traits<std::pair<T1,T2> > {
00572 static std::pair<T1,T2> get(value const &v)
00573 {
00574 if(v.object().size()!=2)
00575 throw bad_value_cast("Object with two members expected");
00576 std::pair<T1,T2> pair(v.get_value<T1>("first"),v.get_value<T2>("second"));
00577 return pair;
00578 }
00579 static void set(value &v,std::pair<T1,T2> const &in)
00580 {
00581 v=json::object();
00582 v.set_value("first",in.first);
00583 v.set_value("second",in.second);
00584 }
00585 };
00586
00587 template<typename T>
00588 struct traits<std::vector<T> > {
00589 static std::vector<T> get(value const &v)
00590 {
00591 std::vector<T> result;
00592 json::array const &a=v.array();
00593 result.resize(a.size());
00594 for(unsigned i=0;i<a.size();i++)
00595 result[i]=a[i].get_value<T>();
00596 return result;
00597 }
00598 static void set(value &v,std::vector<T> const &in)
00599 {
00600 v=json::array();
00601 json::array &a=v.array();
00602 a.resize(in.size());
00603 for(unsigned i=0;i<in.size();i++)
00604 a[i].set_value(in[i]);
00605 }
00606 };
00607
00608
00609 #define CPPCMS_JSON_SPECIALIZE(type,method) \
00610 template<> \
00611 struct traits<type> { \
00612 static type get(value const &v) \
00613 { \
00614 return v.method(); \
00615 } \
00616 static void set(value &v,type const &in)\
00617 { \
00618 v.method(in); \
00619 } \
00620 };
00621
00622 CPPCMS_JSON_SPECIALIZE(bool,boolean);
00623 CPPCMS_JSON_SPECIALIZE(double,number);
00624 CPPCMS_JSON_SPECIALIZE(std::string,str);
00625 CPPCMS_JSON_SPECIALIZE(json::object,object);
00626 CPPCMS_JSON_SPECIALIZE(json::array,array);
00627
00628 #undef CPPCMS_JSON_SPECIALIZE
00629
00630 #define CPPCMS_JSON_SPECIALIZE_INT(type) \
00631 template<> \
00632 struct traits<type> { \
00633 static type get(value const &v) \
00634 { \
00635 type res=static_cast<type>(v.number()); \
00636 if(res!=v.number()) \
00637 throw bad_value_cast(); \
00638 return res; \
00639 } \
00640 static void set(value &v,type const &in) \
00641 { \
00642 if(std::numeric_limits<type>::digits > \
00643 std::numeric_limits<double>::digits \
00644 && static_cast<double>(in)!=in) \
00645 { \
00646 throw bad_value_cast(); \
00647 } \
00648 v.number(static_cast<double>(in)); \
00649 } \
00650 };
00651
00652 CPPCMS_JSON_SPECIALIZE_INT(char)
00653 CPPCMS_JSON_SPECIALIZE_INT(unsigned char)
00654 CPPCMS_JSON_SPECIALIZE_INT(signed char)
00655 CPPCMS_JSON_SPECIALIZE_INT(wchar_t)
00656 CPPCMS_JSON_SPECIALIZE_INT(short)
00657 CPPCMS_JSON_SPECIALIZE_INT(unsigned short)
00658 CPPCMS_JSON_SPECIALIZE_INT(int)
00659 CPPCMS_JSON_SPECIALIZE_INT(unsigned int)
00660 CPPCMS_JSON_SPECIALIZE_INT(long)
00661 CPPCMS_JSON_SPECIALIZE_INT(unsigned long)
00662 CPPCMS_JSON_SPECIALIZE_INT(long long)
00663 CPPCMS_JSON_SPECIALIZE_INT(unsigned long long)
00664
00665 #undef CPPCMS_JSON_SPECIALIZE_INT
00666
00667 template<>
00668 struct traits<float> {
00669 static float get(value const &v)
00670 {
00671 double r=v.number();
00672 if( r < std::numeric_limits<float>::min()
00673 || std::numeric_limits<float>::max() < r )
00674 {
00675 throw bad_value_cast();
00676 }
00677 return static_cast<float>(r);
00678 }
00679 static void set(value &v,float const &in)
00680 {
00681 v.number(in);
00682 }
00683 };
00684
00685 template<>
00686 struct traits<long double> {
00687 static long double get(value const &v)
00688 {
00689 return v.number();
00690 }
00691 static void set(value &v,long double const &in)
00692 {
00693 if( in < std::numeric_limits<double>::min()
00694 || std::numeric_limits<double>::max() < in )
00695 {
00696 throw bad_value_cast();
00697 }
00698 v.number(static_cast<double>(in));
00699 }
00700 };
00701
00702 template<>
00703 struct traits<json::null> {
00704 static void set(value &v,json::null const &)
00705 {
00706 v.null();
00707 }
00708 };
00709
00710 template<int n>
00711 struct traits<char[n]> {
00712 typedef char vtype[n];
00713 static void set(value &v,vtype const &in)
00714 {
00715 v.str(in);
00716 }
00717 };
00718 template<int n>
00719 struct traits<char const [n]> {
00720 typedef char const vtype[n];
00721 static void set(value &v,vtype const &in)
00722 {
00723 v.str(in);
00724 }
00725 };
00726
00727
00728 template<>
00729 struct traits<char const *> {
00730 static void set(value &v,char const * const &in)
00731 {
00732 v.str(in);
00733 }
00734 };
00735
00737
00738
00739 }
00740 }
00741
00742 #endif