46 #if __cplusplus >= 201103L
52 #elif defined(__INTEL_COMPILER)
60 #ifndef PICOJSON_USE_RVALUE_REFERENCE
61 #if (defined(__cpp_rvalue_references) && __cpp_rvalue_references >= 200610) || (defined(_MSC_VER) && _MSC_VER >= 1600)
62 #define PICOJSON_USE_RVALUE_REFERENCE 1
64 #define PICOJSON_USE_RVALUE_REFERENCE 0
66 #endif // PICOJSON_USE_RVALUE_REFERENCE
69 #ifdef PICOJSON_USE_INT64
70 #define __STDC_FORMAT_MACROS
76 #ifndef PICOJSON_USE_LOCALE
77 #define PICOJSON_USE_LOCALE 1
79 #if PICOJSON_USE_LOCALE
85 #ifndef PICOJSON_ASSERT
86 #define PICOJSON_ASSERT(e) \
89 throw std::runtime_error(#e); \
94 #define SNPRINTF _snprintf_s
96 #pragma warning(disable : 4244) // conversion from int to char
97 #pragma warning(disable : 4127) // conditional expression is constant
98 #pragma warning(disable : 4702) // unreachable code
100 #define SNPRINTF snprintf
112 #ifdef PICOJSON_USE_INT64
125 typedef std::map<std::string, value>
object;
129 #ifdef PICOJSON_USE_INT64
143 value(
int type,
bool);
144 explicit value(
bool b);
145 #ifdef PICOJSON_USE_INT64
146 explicit value(int64_t i);
148 explicit value(
double n);
149 explicit value(
const std::string &s);
151 explicit value(
const object &o);
152 #if PICOJSON_USE_RVALUE_REFERENCE
153 explicit value(std::string &&s);
155 explicit value(
object &&o);
157 explicit value(
const char *s);
158 value(
const char *s,
size_t len);
162 #if PICOJSON_USE_RVALUE_REFERENCE
167 template <
typename T>
bool is()
const;
168 template <
typename T>
const T &
get()
const;
169 template <
typename T> T &
get();
170 template <
typename T>
void set(
const T &);
171 #if PICOJSON_USE_RVALUE_REFERENCE
172 template <
typename T>
void set(T &&);
175 const value &
get(
const size_t idx)
const;
176 const value &
get(
const std::string &key)
const;
177 value &
get(
const size_t idx);
178 value &
get(
const std::string &key);
180 bool contains(
const size_t idx)
const;
181 bool contains(
const std::string &key)
const;
182 std::string
to_str()
const;
183 template <
typename Iter>
void serialize(Iter os,
bool prettify =
false)
const;
184 std::string
serialize(
bool prettify =
false)
const;
187 template <
typename T>
value(
const T *);
188 template <
typename Iter>
static void _indent(Iter os,
int indent);
189 template <
typename Iter>
void _serialize(Iter os,
int indent)
const;
190 std::string _serialize(
int indent)
const;
206 INIT(boolean_,
false);
208 #ifdef PICOJSON_USE_INT64
211 INIT(string_,
new std::string());
213 INIT(object_,
new object());
224 #ifdef PICOJSON_USE_INT64
225 inline value::value(int64_t i) : type_(int64_type), u_() {
234 #elif __cplusplus >= 201103L || !(defined(isnan) && defined(isinf))
235 std::isnan(n) || std::isinf(n)
240 throw std::overflow_error(
"");
257 #if PICOJSON_USE_RVALUE_REFERENCE
259 u_.
string_ =
new std::string(std::move(s));
279 inline void value::clear() {
322 #if PICOJSON_USE_RVALUE_REFERENCE
332 std::swap(type_, x.type_);
336 #define IS(ctype, jtype) \
337 template <> inline bool value::is<ctype>() const { \
338 return type_ == jtype##_type; \
342 #ifdef PICOJSON_USE_INT64
345 IS(std::string,
string)
349 template <>
inline bool value::is<double>()
const {
351 #ifdef PICOJSON_USE_INT64
352 || type_ == int64_type
357 #define GET(ctype, var) \
358 template <> inline const ctype &value::get<ctype>() const { \
359 PICOJSON_ASSERT("type mismatch! call is<type>() before get<type>()" && is<ctype>()); \
362 template <> inline ctype &value::get<ctype>() { \
363 PICOJSON_ASSERT("type mismatch! call is<type>() before get<type>()" && is<ctype>()); \
366 GET(
bool, u_.boolean_)
367 GET(std::
string, *u_.string_)
368 GET(array, *u_.array_)
369 GET(
object, *u_.object_)
370 #ifdef PICOJSON_USE_INT64
372 (type_ == int64_type && (const_cast<value *>(
this)->type_ =
number_type, const_cast<value *>(
this)->u_.number_ = u_.int64_),
374 GET(int64_t, u_.int64_)
376 GET(
double, u_.number_)
380 #define SET(ctype, jtype, setter) \
381 template <> inline void value::set<ctype>(const ctype &_val) { \
383 type_ = jtype##_type; \
386 SET(
bool,
boolean, u_.boolean_ = _val;)
387 SET(std::
string,
string, u_.string_ = new std::
string(_val);)
388 SET(array, array, u_.array_ = new array(_val);)
389 SET(
object,
object, u_.object_ = new
object(_val);)
390 SET(
double, number, u_.number_ = _val;)
391 #ifdef PICOJSON_USE_INT64
392 SET(int64_t, int64, u_.int64_ = _val;)
396 #if PICOJSON_USE_RVALUE_REFERENCE
397 #define MOVESET(ctype, jtype, setter) \
398 template <> inline void value::set<ctype>(ctype && _val) { \
400 type_ = jtype##_type; \
403 MOVESET(std::string,
string, u_.string_ =
new std::string(std::move(_val));)
404 MOVESET(array, array, u_.array_ = new array(std::move(_val));)
405 MOVESET(
object,
object, u_.object_ = new
object(std::move(_val));)
417 #ifdef PICOJSON_USE_INT64
419 return u_.int64_ != 0;
443 object::const_iterator i =
u_.
object_->find(key);
444 return i !=
u_.
object_->end() ? i->second : s_null;
450 object::iterator i =
u_.
object_->find(key);
451 return i !=
u_.
object_->end() ? i->second : s_null;
461 object::const_iterator i =
u_.
object_->find(key);
471 #ifdef PICOJSON_USE_INT64
473 char buf[
sizeof(
"-9223372036854775808")];
474 SNPRINTF(buf,
sizeof(buf),
"%" PRId64,
u_.int64_);
482 #if PICOJSON_USE_LOCALE
483 char *decimal_point = localeconv()->decimal_point;
484 if (strcmp(decimal_point,
".") != 0) {
485 size_t decimal_point_len = strlen(decimal_point);
486 for (
char *p = buf; *p !=
'\0'; ++p) {
487 if (strncmp(p, decimal_point, decimal_point_len) == 0) {
488 return std::string(buf, p) +
"." + (p + decimal_point_len);
507 return std::string();
510 template <
typename Iter>
void copy(
const std::string &s, Iter oi) {
518 #define MAP(val, sym) \
532 if (static_cast<unsigned char>(c) < 0x20 || c == 0x7f) {
534 SNPRINTF(buf,
sizeof(buf),
"\\u%04x", c & 0xff);
544 template <
typename Iter>
void serialize_str(
const std::string &s, Iter oi) {
547 std::for_each(s.begin(), s.end(), process_char);
552 return _serialize(oi, prettify ? 0 : -1);
556 return _serialize(prettify ? 0 : -1);
559 template <
typename Iter>
void value::_indent(Iter oi,
int indent) {
566 template <
typename Iter>
void value::_serialize(Iter oi,
int indent)
const {
576 for (array::const_iterator i =
u_.
array_->begin(); i !=
u_.
array_->end(); ++i) {
583 i->_serialize(oi, indent);
611 i->second._serialize(oi, indent);
631 inline std::string value::_serialize(
int indent)
const {
633 _serialize(std::back_inserter(s), indent);
637 template <
typename Iter>
class input {
677 if (!(ch ==
' ' || ch ==
'\t' || ch ==
'\n' || ch ==
'\r')) {
685 if (
getc() != expected) {
691 bool match(
const std::string &pattern) {
692 for (std::string::const_iterator pi(pattern.begin()); pi != pattern.end(); ++pi) {
704 for (
int i = 0; i < 4; i++) {
705 if ((hex = in.
getc()) == -1) {
708 if (
'0' <= hex && hex <=
'9') {
710 }
else if (
'A' <= hex && hex <=
'F') {
712 }
else if (
'a' <= hex && hex <=
'f') {
718 uni_ch = uni_ch * 16 + hex;
728 if (0xd800 <= uni_ch && uni_ch <= 0xdfff) {
729 if (0xdc00 <= uni_ch) {
734 if (in.
getc() !=
'\\' || in.
getc() !=
'u') {
739 if (!(0xdc00 <= second && second <= 0xdfff)) {
742 uni_ch = ((uni_ch - 0xd800) << 10) | ((second - 0xdc00) & 0x3ff);
746 out.push_back(static_cast<char>(uni_ch));
748 if (uni_ch < 0x800) {
749 out.push_back(static_cast<char>(0xc0 | (uni_ch >> 6)));
751 if (uni_ch < 0x10000) {
752 out.push_back(static_cast<char>(0xe0 | (uni_ch >> 12)));
754 out.push_back(static_cast<char>(0xf0 | (uni_ch >> 18)));
755 out.push_back(static_cast<char>(0x80 | ((uni_ch >> 12) & 0x3f)));
757 out.push_back(static_cast<char>(0x80 | ((uni_ch >> 6) & 0x3f)));
759 out.push_back(static_cast<char>(0x80 | (uni_ch & 0x3f)));
770 }
else if (ch ==
'"') {
772 }
else if (ch ==
'\\') {
773 if ((ch = in.
getc()) == -1) {
777 #define MAP(sym, val) \
779 out.push_back(val); \
799 out.push_back(static_cast<char>(ch));
806 if (!ctx.parse_array_start()) {
811 return ctx.parse_array_stop(idx);
814 if (!ctx.parse_array_item(in, idx)) {
819 return in.
expect(
']') && ctx.parse_array_stop(idx);
823 if (!ctx.parse_object_start()) {
834 if (!ctx.parse_object_item(in, key)) {
845 if ((
'0' <= ch && ch <=
'9') || ch ==
'+' || ch ==
'-' || ch ==
'e' || ch ==
'E') {
846 num_str.push_back(static_cast<char>(ch));
847 }
else if (ch ==
'.') {
848 #if PICOJSON_USE_LOCALE
849 num_str += localeconv()->decimal_point;
851 num_str.push_back(
'.');
865 #define IS(ch, text, op) \
867 if (in.match(text) && op) { \
872 IS(
'n',
"ull", ctx.set_null());
873 IS(
'f',
"alse", ctx.set_bool(
false));
874 IS(
't',
"rue", ctx.set_bool(
true));
877 return ctx.parse_string(in);
883 if ((
'0' <= ch && ch <=
'9') || ch ==
'-') {
888 if (num_str.empty()) {
891 #ifdef PICOJSON_USE_INT64
894 intmax_t ival = strtoimax(num_str.c_str(), &endp, 10);
895 if (errno == 0 && std::numeric_limits<int64_t>::min() <= ival && ival <= std::numeric_limits<int64_t>::max() &&
896 endp == num_str.c_str() + num_str.size()) {
902 f = strtod(num_str.c_str(), &endp);
903 if (endp == num_str.c_str() + num_str.size()) {
923 #ifdef PICOJSON_USE_INT64
924 bool set_int64(int64_t) {
966 #ifdef PICOJSON_USE_INT64
967 bool set_int64(int64_t i) {
986 a.push_back(
value());
998 object &o =
out_->
get<
object>();
1024 #ifdef PICOJSON_USE_INT64
1025 bool set_int64(int64_t) {
1040 return _parse(*
this, in);
1049 return _parse(*
this, in);
1058 template <
typename Iter>
inline std::string
parse(
value &out, Iter &pos,
const Iter &last) {
1060 pos =
parse(out, pos, last, &err);
1064 template <
typename Context,
typename Iter>
inline Iter
_parse(Context &ctx,
const Iter &first,
const Iter &last, std::string *err) {
1066 if (!
_parse(ctx, in) && err != NULL) {
1068 SNPRINTF(buf,
sizeof(buf),
"syntax error at line %d near: ", in.
line());
1072 if (ch == -1 || ch ==
'\n') {
1074 }
else if (ch >=
' ') {
1075 err->push_back(static_cast<char>(ch));
1082 template <
typename Iter>
inline Iter
parse(
value &out,
const Iter &first,
const Iter &last, std::string *err) {
1084 return _parse(ctx, first, last, err);
1089 parse(out, s.begin(), s.end(), &err);
1095 parse(out, std::istreambuf_iterator<char>(is.rdbuf()), std::istreambuf_iterator<char>(), &err);
1113 #define PICOJSON_CMP(type) \
1115 return y.is<type>() && x.get<type>() == y.get<type>()
1134 #if !PICOJSON_USE_RVALUE_REFERENCE
1147 is.setstate(std::ios::failbit);
1153 x.
serialize(std::ostream_iterator<char>(os));
1157 #pragma warning(pop)
std::vector< value > array
Definition: picojson.h:124
bool parse_array_start()
Definition: picojson.h:1036
Definition: picojson.h:108
Definition: picojson.h:126
Definition: picojson.h:1099
bool set_bool(bool)
Definition: picojson.h:1021
bool evaluate_as_boolean() const
Definition: picojson.h:409
bool parse_array_item(input< Iter > &, size_t)
Definition: picojson.h:937
Definition: picojson.h:109
value * out_
Definition: picojson.h:953
bool parse_array_item(input< Iter > &in, size_t)
Definition: picojson.h:984
bool _parse_codepoint(String &out, input< Iter > &in)
Definition: picojson.h:723
std::string * string_
Definition: picojson.h:132
std::string parse(value &out, Iter &pos, const Iter &last)
Definition: picojson.h:1058
void operator()(char c)
Definition: picojson.h:516
bool set_null()
Definition: picojson.h:917
bool set_number(double)
Definition: picojson.h:1029
bool parse_object_item(input< Iter > &, const std::string &)
Definition: picojson.h:946
bool parse_string(input< Iter > &)
Definition: picojson.h:931
bool parse_array_item(input< Iter > &in, size_t)
Definition: picojson.h:1039
bool parse_object_item(input< Iter > &in, const std::string &key)
Definition: picojson.h:997
Definition: picojson.h:1008
bool set_null()
Definition: picojson.h:1018
object * object_
Definition: picojson.h:134
bool boolean_
Definition: picojson.h:127
std::string to_str() const
Definition: picojson.h:465
bool parse_array_stop(size_t)
Definition: picojson.h:940
void swap(value &x)
Definition: picojson.h:331
#define PICOJSON_ASSERT(e)
Definition: picojson.h:86
void set_last_error(const std::string &s)
Definition: picojson.h:1102
bool parse_array_start()
Definition: picojson.h:934
value & operator=(const value &x)
Definition: picojson.h:314
Definition: picojson.h:951
const std::string & get_last_error()
Definition: picojson.h:1106
bool operator==(const value &x, const value &y)
Definition: picojson.h:1110
#define GET(ctype, var)
Definition: picojson.h:357
std::string _parse_number(input< Iter > &in)
Definition: picojson.h:841
bool parse_array_stop(size_t)
Definition: picojson.h:1042
_storage u_
Definition: picojson.h:139
null_parse_context()
Definition: picojson.h:1016
Definition: picojson.h:118
Definition: picojson.h:107
bool parse_array_stop(size_t)
Definition: picojson.h:990
Definition: picojson.h:110
std::map< std::string, value > object
Definition: picojson.h:125
Definition: picojson.h:122
bool parse_object_start()
Definition: picojson.h:1045
bool parse_string(input< Iter > &in)
Definition: picojson.h:976
bool _parse_array(Context &ctx, input< Iter > &in)
Definition: picojson.h:805
Definition: picojson.h:120
default_parse_context(value *out)
Definition: picojson.h:956
int type_
Definition: picojson.h:138
std::ostream & operator<<(std::ostream &os, const picojson::value &x)
Definition: picojson.h:1152
bool operator!=(const value &x, const value &y)
Definition: picojson.h:1129
Definition: picojson.h:514
array * array_
Definition: picojson.h:133
#define SET(ctype, jtype, setter)
Definition: picojson.h:380
bool _parse_string(String &out, input< Iter > &in)
Definition: picojson.h:764
Definition: picojson.h:915
static std::string s
Definition: picojson.h:1099
void push_back(int)
Definition: picojson.h:1011
int _parse_quadhex(input< Iter > &in)
Definition: picojson.h:702
bool contains(const size_t idx) const
Definition: picojson.h:454
bool _parse(Context &ctx, input< Iter > &in)
Definition: picojson.h:861
Definition: picojson.h:111
std::istream & operator>>(std::istream &is, picojson::value &x)
Definition: picojson.h:1142
Definition: picojson.h:1010
value()
Definition: picojson.h:197
#define PICOJSON_CMP(type)
bool parse_string(input< Iter > &in)
Definition: picojson.h:1032
bool parse_object_start()
Definition: picojson.h:993
double number_
Definition: picojson.h:128
~value()
Definition: picojson.h:294
bool set_bool(bool b)
Definition: picojson.h:962
#define SNPRINTF
Definition: picojson.h:100
void serialize_str(const std::string &s, Iter oi)
Definition: picojson.h:544
bool parse_array_start()
Definition: picojson.h:980
#define IS(ctype, jtype)
Definition: picojson.h:336
bool set_bool(bool)
Definition: picojson.h:920
bool _parse_object(Context &ctx, input< Iter > &in)
Definition: picojson.h:822
bool parse_object_start()
Definition: picojson.h:943
Iter oi
Definition: picojson.h:515
bool parse_object_item(input< Iter > &in, const std::string &)
Definition: picojson.h:1048
bool set_number(double)
Definition: picojson.h:928
bool set_null()
Definition: picojson.h:958
void copy(const std::string &s, Iter oi)
Definition: picojson.h:510
bool set_number(double f)
Definition: picojson.h:972
value::array array
Definition: picojson.h:194
Definition: picojson.h:106
value::object object
Definition: picojson.h:195
void serialize(Iter os, bool prettify=false) const
Definition: picojson.h:551