32 case '\t': s++;
break;
33 case '\n': s++;
break;
34 case '\r': s++;
break;
44 if (c >=
'0' && c <=
'9')
46 if (c >=
'a' && c <=
'f')
48 if (c >=
'A' && c <=
'F')
57 for (
int i=0; i<4; i++) {
63 unicode = unicode*16 + v;
74 if (unicode >= 0 && unicode <= 0x7F) {
76 buf[0] = unicode & 0x7F;
83 if (unicode >= 0x80 && unicode <= 0x7FF) {
85 buf[0] = 0x80|0x40|((unicode>>6)&0x1F);
86 buf[1] = 0x80|((unicode>>0)&0x3F);
91 if (unicode >= 0x800 && unicode <= 0xFFFF) {
93 buf[0] = 0x80|0x40|0x20|((unicode>>12)&0xF);
94 buf[1] = 0x80|((unicode>>6)&0x3F);
95 buf[2] = 0x80|((unicode>>0)&0x3F);
104 static std::string
xparse_string(
const char* s,
const char** sout,
bool *error)
116 }
else if (*s ==
'\"') {
120 }
else if (*s ==
'\\') {
135 case '\"': v +=
'\"'; s++;
break;
136 case '\\': v +=
'\\'; s++;
break;
137 case '/': v +=
'/'; s++;
break;
138 case 'b': v +=
'\b'; s++;
break;
139 case 'f': v +=
'\f'; s++;
break;
140 case 'n': v +=
'\n'; s++;
break;
141 case 'r': v +=
'\r'; s++;
break;
142 case 't': v +=
'\t'; s++;
break;
222 return MJsonNode::MakeError(n,
"unexpected char after array element, should be \',\' or \']\'", sin, s);
250 }
else if (*s !=
'\"') {
252 return MJsonNode::MakeError(n,
"unexpected char while parsing object, should be \"\"\"", sin, s);
257 if (error || name.length() < 1) {
266 return MJsonNode::MakeError(n,
"unexpected end of string after name of object element", sin, s);
267 }
else if (*s !=
':') {
269 return MJsonNode::MakeError(n,
"unexpected char after name of object element, should be \":\"", sin, s);
301 return MJsonNode::MakeError(n,
"unexpected char after object element, should be \"}\" or \",\"", sin, s);
341 const int kMAX = INT_MAX/10;
342 const int kLAST = INT_MAX - kMAX*10;
344 for ( ; *s != 0; s++) {
349 if (v == kMAX && vadd > kLAST) {
359 const int kMIN = INT_MIN/10;
360 const int kLAST = -(INT_MIN - kMIN*10);
362 for ( ; *s != 0; s++) {
367 if (v == kMIN && vadd > kLAST) {
388 printf(
"atoi test failed: [%s] [%s] -> %d (0x%x) != %d (0x%x)\n", (sign>0)?
"+":
"-", s, vv, vv, v, v);
389 assert(!
"mjson self test: my atoi() is broken, bye!");
476 if (*s ==
'e' || *s ==
'E') {
497 if (expsign < 0 || sfrac.length() > 0) {
499 double v1 = atof(sint.c_str());
502 const char* p = sfrac.c_str();
503 for ( ; *p != 0; p++, vm/=10.0) {
509 if (e < 0 || e > 400) {
512 printf(
"overflow!\n");
517 double inf =
one/zero;
527 ee = pow(10, (
double)(expsign*e));
528 double v = sign*(v1+v2)*ee;
538 if (e < 0 || e > 400) {
545 double inf =
one/zero;
550 for (
int ee=0; ee<e; ee++)
570 double vv = atof(sint.c_str());
587 if (s[0] ==
'n' && s[1] ==
'u' && s[2] ==
'l' && s[3] ==
'l') {
598 if (s[0] ==
't' && s[1] ==
'r' && s[2] ==
'u' && s[3] ==
'e') {
609 if (s[0] ==
'f' && s[1] ==
'a' && s[2] ==
'l' && s[3] ==
's' && s[4] ==
'e') {
625 }
else if (*s ==
'{') {
627 }
else if (*s ==
'\"') {
629 }
else if (*s ==
'-') {
631 }
else if (*s >=
'0' && *s <=
'9') {
633 }
else if (*s ==
'n') {
635 }
else if (*s ==
't') {
637 }
else if (*s ==
'f') {
653 for (
unsigned i=0; i<
subnodes.size(); i++)
683 case '\"': v +=
"\\\""; s++;
break;
684 case '\\': v +=
"\\\\"; s++;
break;
686 case '\b': v +=
"\\b"; s++;
break;
687 case '\f': v +=
"\\f"; s++;
break;
688 case '\n': v +=
"\\n"; s++;
break;
689 case '\r': v +=
"\\r"; s++;
break;
690 case '\t': v +=
"\\t"; s++;
break;
727 return "\"Infinity\"";
729 return "\"-Infinity\"";
731 assert(!
"this cannot happen!");
742 for (
unsigned i=0; i<
subnodes.size(); i++) {
782 return "arraybuffer";
784 return std::string(
"json parse error: ") +
stringvalue;
786 assert(!
"should not come here");
800 strncpy(sample, serror, 31);
802 int offset = serror-sin;
805 for (
const char* s = sin; s != serror; s++) {
815 sprintf(msg,
" at char \"%c\" file offset %d, line %d position %d, around text \"%s\"", *serror, offset, lineno, lineoff, sample);
890 assert(!
"not an array");
902 assert(!
"not an object");
1045 default:
return "UNKNOWN";
1062 for (
int i=0; i<nest; i++)
1068 printf(
"Node type %d (%s)", type, TypeToString(type));
1070 default: printf(
"\n");
break;
1071 case MJSON_STRING: printf(
", value [%s]\n", stringvalue.c_str());
break;
1072 case MJSON_INT: printf(
", value %d\n", intvalue);
break;
1073 case MJSON_NUMBER: printf(
", value %g\n", numbervalue);
break;
1074 case MJSON_BOOL: printf(
", value %d\n", intvalue);
break;
1076 case MJSON_JSON: printf(
", json [%s]\n", stringvalue.c_str());
break;
1077 case MJSON_ARRAYBUFFER: printf(
", arraybuffer size %d\n", (
int)arraybuffer_size);
break;
1080 for (
unsigned i=0; i<subnodes.size(); i++) {
1082 printf(
"element %d: ", i);
1083 subnodes[i]->Dump(nest+1);
1088 for (
unsigned i=0; i<objectnames.size(); i++) {
1090 printf(
"%s: ", objectnames[i].c_str());
1091 subnodes[i]->Dump(nest+1);
1095 printf(
": %s\n", stringvalue.c_str());
1096 for (
unsigned i=0; i<subnodes.size(); i++) {
1098 printf(
"errorelement %d: ", i);
1099 subnodes[i]->Dump(nest+1);
1110 for (
unsigned i=0; i<n->
subnodes.size(); i++) {
std::string GetString() const
find subnode with given name, NULL if not object, NULL is name not found
static MJsonNode * MakeJSON(const char *json)
void Dump(int nest=0) const
return node type as string
#define MJSON_ARRAYBUFFER
static MJsonNode * MakeArray()
MJsonNode * Copy() const
dump the subtree to standard output
const MJsonNodeVector * GetArray() const
get node type: MJSON_xxx
int GetType() const
delete a node from an object
int GetInt() const
get string value, "" if not string or value is JSON "null"
void AddToArray(MJsonNode *node)
static MJsonNode * MakeNumber(double value)
static std::string Encode(const char *s)
std::vector< MJsonNode * > MJsonNodeVector
std::vector< std::string > MJsonStringVector
MJsonNode(int type)
make a copy of the json tree
static MJsonNode * MakeObject()
void AddToObject(const char *name, MJsonNode *node)
add node to an array. the array takes ownership of this node
double GetDouble() const
get integer value, 0 if not an integer or value is JSON "null"
const MJsonNodeVector * GetObjectNodes() const
get array of object names, NULL if not object, empty array if value is JSON "null"
static MJsonNode * MakeBool(bool value)
std::string Stringify(int flags=0) const
static MJsonNode * MakeString(const char *value)
void DeleteObjectNode(const char *name)
add node to an object. the object takes ownership of this node
bool GetBool() const
get number or integer value, 0 if not a number or value is JSON "null"
static std::string EncodeDouble(double v)
void GetArrayBuffer(const char **pptr, size_t *psize) const
get boolean value, false if not a boolean or value is JSON "null"
MJsonStringVector objectnames
const MJsonStringVector * GetObjectNames() const
get array value, NULL if not array, empty array if value is JSON "null"
static MJsonNode * MakeError(MJsonNode *errornode, const char *errormessage, const char *sin, const char *serror)
the node takes ownership of the buffer
const MJsonNode * FindObjectNode(const char *name) const
get array of object subnodes, NULL if not object, empty array if value is JSON "null"
static MJsonNode * MakeArrayBuffer(char *ptr, size_t size)
static MJsonNode * MakeNull()
std::string GetError() const
static MJsonNode * Parse(const char *jsonstring)
static std::string EncodeInt(int v)
static MJsonNode * MakeInt(int value)
static const char * TypeToString(int type)
get error message from MJSON_ERROR nodes
static MJsonNode * parse_number(const char *sin, const char *s, const char **sout)
static char toHexChar(int c)
static std::string xoutput_unicode(int unicode, bool *error)
static void test_atoi_with_overflow()
static int patoi_with_overflow(const char *s)
static MJsonNode * parse_string(const char *sin, const char *s, const char **sout)
static int xparse_unicode(const char *s, const char **sout)
static MJsonNode * parse_false(const char *sin, const char *s, const char **sout)
static MJsonNode * parse_true(const char *sin, const char *s, const char **sout)
static MJsonNode * parse_something(const char *sin, const char *s, const char **sout)
static const char * skip_spaces(const char *s)
static int matoi_with_overflow(const char *s)
static std::string xparse_string(const char *s, const char **sout, bool *error)
static int hexToInt(char c)
static MJsonNode * parse_object(const char *sin, const char *s, const char **sout)
static void pnest(int nest)
static std::string parse_digits(const char *s, const char **sout)
static MJsonNode * parse_null(const char *sin, const char *s, const char **sout)
static MJsonNode * parse_array(const char *sin, const char *s, const char **sout)
static void test_atoi_with_overflow_value(int sign, const char *s, int v)