33      case '\t': s++; 
break;
 
   34      case '\n': s++; 
break;
 
   35      case '\r': s++; 
break;
 
 
   45   if (c >= 
'0' && c <= 
'9')
 
   47   if (c >= 
'a' && c <= 
'f')
 
   49   if (c >= 
'A' && c <= 
'F')
 
 
   58   for (
int i=0; i<4; i++) {
 
   64      unicode = unicode*16 + v;
 
 
   75   if (unicode >= 0 && unicode <= 0x7F) { 
 
   77      buf[0] = unicode & 0x7F;
 
   84   if (unicode >= 0x80 && unicode <= 0x7FF) { 
 
   86      buf[0] = 0x80|0x40|((unicode>>6)&0x1F); 
 
   87      buf[1] = 0x80|((unicode>>0)&0x3F); 
 
   92   if (unicode >= 0x800 && unicode <= 0xFFFF) { 
 
   94      buf[0] = 0x80|0x40|0x20|((unicode>>12)&0xF); 
 
   95      buf[1] = 0x80|((unicode>>6)&0x3F); 
 
   96      buf[2] = 0x80|((unicode>>0)&0x3F); 
 
 
  105static std::string 
xparse_string(
const char* s, 
const char** sout, 
bool *error)
 
  117      } 
else if (*s == 
'\"') {
 
  121      } 
else if (*s == 
'\\') {
 
  136         case '\"': v += 
'\"'; s++; 
break;
 
  137         case '\\': v += 
'\\'; s++; 
break;
 
  138         case '/': v += 
'/';  s++; 
break;
 
  139         case 'b': v += 
'\b'; s++; 
break;
 
  140         case 'f': v += 
'\f'; s++; 
break;
 
  141         case 'n': v += 
'\n'; s++; 
break;
 
  142         case 'r': v += 
'\r'; s++; 
break;
 
  143         case 't': v += 
'\t'; s++; 
break;
 
 
  223      return MJsonNode::MakeError(n, 
"unexpected char after array element, should be \',\' or \']\'", sin, s);
 
 
  251      } 
else if (*s != 
'\"') {
 
  253         return MJsonNode::MakeError(n, 
"unexpected char while parsing object, should be \"\"\"", sin, s);
 
  258      if (error || name.length() < 1) {
 
  267         return MJsonNode::MakeError(n, 
"unexpected end of string after name of object element", sin, s);
 
  268      } 
else if (*s != 
':') {
 
  270         return MJsonNode::MakeError(n, 
"unexpected char after name of object element, should be \":\"", sin, s);
 
  302      return MJsonNode::MakeError(n, 
"unexpected char after object element, should be \"}\" or \",\"", sin, s);
 
 
  345   number = std::strtoll(str, &end, 10);
 
  347   if ((number == LLONG_MAX || number == LLONG_MIN) && errno == ERANGE)
 
 
  372   printf(
"atoll test failed: [%s] -> %lld (0x%llx) != %lld (0x%llx)\n", s, vv, vv, v, v);
 
  373   assert(!
"mjson self test: my atoll() is broken, bye!");
 
 
  477   if (*s == 
'e' || *s == 
'E') {
 
  501   if (expsign < 0 || sfrac.length() > 0) {
 
  503      double v1 = atof(sint.c_str());
 
  506      const char* p = sfrac.c_str();
 
  507      for ( ; *p != 0; p++, vm/=10.0) {
 
  513      if (flag && (e < 0 || e > 400)) {
 
  516         printf(
"overflow!\n");
 
  521            double inf = 
one/zero; 
 
  531         ee = pow(10, (
double)(expsign*e));
 
  532      double v = sign*(v1+v2)*ee;
 
  542      if (flag && (e < 0 || e > 400)) {
 
  549         double inf = 
one/zero; 
 
  554      for (
int ee=0; ee<e; ee++)
 
  560      std::string sstr = sign == 1 ? sint : 
"-" + sint;
 
  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;
 
 
  713   snprintf(buf, 
sizeof(buf), 
"%lld", value);
 
 
  719   if (isfinite(numbervalue)) {
 
  721      snprintf(buf, 
sizeof(buf), 
"%.16e", numbervalue);
 
  723   } 
else if (isnan(numbervalue)) {
 
  725   } 
else if (isinf(numbervalue)) {
 
  727         return "\"Infinity\"";
 
  729         return "\"-Infinity\"";
 
  731      assert(!
"this cannot happen!");
 
 
  742      for (
size_t i=0; i<
subnodes.size(); i++) {
 
  782      return "arraybuffer";
 
  784      return std::string(
"json parse error: ") + 
string_value;
 
  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      snprintf(msg, 
sizeof(msg), 
" at char \"%c\" file offset %d, line %d position %d, around text \"%s\"", *serror, offset, lineno, lineoff, sample);
 
 
  889   assert(!
"not an array");
 
 
  901   assert(!
"not an object");
 
 
 1050   default: 
return "UNKNOWN";
 
 
 1067   for (
int i=0; i<nest; i++)
 
 
 1073   printf(
"Node type %d (%s)", type, TypeToString(type));
 
 1075   default: printf(
"\n"); 
break;
 
 1076   case MJSON_STRING: printf(
", value [%s]\n", string_value.c_str()); 
break;
 
 1077   case MJSON_INT: printf(
", value %lld\n", ll_value); 
break;
 
 1078   case MJSON_NUMBER: printf(
", value %g\n", double_value); 
break;
 
 1079   case MJSON_BOOL: printf(
", value %lld\n", ll_value); 
break;
 
 1081   case MJSON_JSON: printf(
", json [%s]\n", string_value.c_str()); 
break;
 
 1082   case MJSON_ARRAYBUFFER: printf(
", arraybuffer size %zu\n", arraybuffer_size); 
break;
 
 1085      for (
size_t i=0; i<subnodes.size(); i++) {
 
 1087         printf(
"element %zu: ", i);
 
 1088         subnodes[i]->Dump(nest+1);
 
 1093      for (
size_t i=0; i<object_names.size(); i++) {
 
 1095         printf(
"%s: ", object_names[i].c_str());
 
 1096         subnodes[i]->Dump(nest+1);
 
 1100      printf(
": %s\n", string_value.c_str());
 
 1101      for (
size_t i=0; i<subnodes.size(); i++) {
 
 1103         printf(
"errorelement %zu: ", i);
 
 1104         subnodes[i]->Dump(nest+1);
 
 
 1115   for (
size_t 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
long long GetLL() const
get integer value, 0 if not an integer or value is JSON "null"
MJsonStringVector object_names
int GetType() const
delete a node from an object
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
long long GetInt() const
get string value, "" if not string or value is JSON "null"
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 64-bit long long 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 MJsonNode * MakeInt(long long value)
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"
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 std::string EncodeLL(long long v)
static MJsonNode * MakeNull()
std::string GetError() const
static MJsonNode * Parse(const char *jsonstring)
static const char * TypeToString(int type)
get error message from MJSON_ERROR nodes
static char toHexChar(int c)
static std::string xoutput_unicode(int unicode, bool *error)
bool atoll_with_overflow(const char *str, long long &number)
static int xparse_unicode(const char *s, const char **sout)
static void test_atoll_with_overflow_value(const char *s, long long v, bool flag)
static MJsonNode * parse_something(const char *sin, const char *s, const char **sout)
static MJsonNode * parse_string(const char *sin, 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_object(const char *sin, const char *s, const char **sout)
static TestAtollWithOverflow runme
static std::string xparse_string(const char *s, const char **sout, bool *error)
static int hexToInt(char c)
static MJsonNode * parse_null(const char *sin, const char *s, const char **sout)
static void pnest(int nest)
static const char * skip_spaces(const char *s)
static std::string parse_digits(const char *s, const char **sout)
static MJsonNode * parse_number(const char *sin, const char *s, const char **sout)
static void test_atoll_with_overflow()
static MJsonNode * parse_array(const char *sin, const char *s, const char **sout)