diff options
author | Vadim Dashevskiy <watcherhd@gmail.com> | 2012-06-23 17:30:18 +0000 |
---|---|---|
committer | Vadim Dashevskiy <watcherhd@gmail.com> | 2012-06-23 17:30:18 +0000 |
commit | a02c7c0f1bd98583cdaa4154f402eb66009e4198 (patch) | |
tree | 306ab51b01f00fa74b008bfd8a2a0faefd028fb7 /plugins/JSON/Source/JSONWorker.cpp | |
parent | 240b769d44fe6c50cabbf311f8e9fb1fae7cd80e (diff) |
git-svn-id: http://svn.miranda-ng.org/main/trunk@574 1316c22d-e87f-b044-9b9b-93d7a3e3ba9c
Diffstat (limited to 'plugins/JSON/Source/JSONWorker.cpp')
-rw-r--r-- | plugins/JSON/Source/JSONWorker.cpp | 676 |
1 files changed, 0 insertions, 676 deletions
diff --git a/plugins/JSON/Source/JSONWorker.cpp b/plugins/JSON/Source/JSONWorker.cpp deleted file mode 100644 index 245e1568dc..0000000000 --- a/plugins/JSON/Source/JSONWorker.cpp +++ /dev/null @@ -1,676 +0,0 @@ -#include "JSONWorker.h" - -#ifdef JSON_VALIDATE -JSONNode JSONWorker::validate(const json_string & json){ - JSONNode res = parse(json); - if (!res.validate()) { - throw std::invalid_argument(EMPTY_STRING2); - } - return JSONNode(true, res); //forces it to simply return the original interal, even with ref counting off -} -#endif - -JSONNode JSONWorker::parse(const json_string & json){ - json_auto<json_char> s; - #if defined JSON_DEBUG || defined JSON_SAFE - json_char lastchar; - s.set(RemoveWhiteSpace(json, lastchar)); - #else - s.set(RemoveWhiteSpace(json)); - #endif - - #ifdef JSON_COMMENTS - json_char firstchar = s.ptr[0]; - json_string _comment; - json_char * runner = s.ptr; - if (firstchar == '\5') { //multiple comments will be consolidated into one - newcomment: - while(*(++runner) != '\5') { - JSON_ASSERT(*runner, JSON_TEXT("Removing white space failed")); - _comment += *runner; - } - firstchar = *(++runner); //step past the trailing tag - if (firstchar == '\5') { - _comment += '\n'; - goto newcomment; - } - } - #else - const json_char firstchar = s.ptr[0]; - #endif - - switch (firstchar){ - case '{': - case '[': - #if defined JSON_DEBUG || defined JSON_SAFE - if (firstchar == '[') { - if (lastchar != ']') { - JSON_FAIL(JSON_TEXT("Missing final ]")); - break; - } - } else { - if (lastchar != '}') { - JSON_FAIL(JSON_TEXT("Missing final }")); - break; - } - } - #endif - #ifdef JSON_COMMENTS - JSONNode foo(runner); - foo.set_comment(_comment); - return JSONNode(true, foo); //forces it to simply return the original interal, even with ref counting off - #else - return JSONNode(s.ptr); - #endif - } - - JSON_FAIL(JSON_TEXT("Not JSON!")); - throw std::invalid_argument(EMPTY_STRING2); -} - -#define QUOTECASE()\ - case JSON_TEXT('\"'):\ - while (*(++p) != JSON_TEXT('\"')) {\ - JSON_ASSERT_SAFE(*p, JSON_TEXT("Null terminator inside of a quotation"), return json_string::npos;);\ - }\ - break; - -#ifdef JSON_DEBUG - #define NULLCASE(error)\ - case JSON_TEXT('\0'):\ - JSON_FAIL_SAFE(error, return json_string::npos;);\ - break; -#else - #define NULLCASE(error) -#endif - -#define BRACKET(left, right)\ - case left: {\ - size_t brac = 1;\ - while (brac){\ - switch (*(++p)) {\ - case right:\ - --brac;\ - break;\ - case left:\ - ++brac;\ - break;\ - QUOTECASE()\ - NULLCASE(JSON_TEXT("Null terminator inside of a bracket"))\ - }\ - }\ - break;}\ - case right:\ - return json_string::npos; - -size_t JSONWorker::FindNextRelevant(json_char ch, const json_string & value_t, const size_t pos){ - const json_char * start = value_t.c_str(); - const json_char * p = start + pos; //start at the correct offset - do { - if (*p == ch) return p - start; - switch (*p){ - BRACKET(JSON_TEXT('['), JSON_TEXT(']')) - BRACKET(JSON_TEXT('{'), JSON_TEXT('}')) - QUOTECASE() - } - } while(*(++p)); - return json_string::npos; -} - -#ifdef JSON_COMMENTS - #define COMMENT_DELIMITER() *runner++ = '\5' - #define AND_RUNNER ,runner - inline void SingleLineComment(const json_char * & p, json_char * & runner){ - COMMENT_DELIMITER(); - while((*(++p)) && (*p != JSON_TEXT('\n'))) { - *runner++ = *p; - } - COMMENT_DELIMITER(); - } -#else - #define COMMENT_DELIMITER() (void)0 - #define AND_RUNNER -#endif - -inline void SingleLineComment(const json_char * & p){ - while((*(++p)) && (*p != JSON_TEXT('\n'))); -} - - -#if defined JSON_DEBUG || defined JSON_SAFE - json_char * JSONWorker::RemoveWhiteSpace(const json_string & value_t, json_char & last){ -#else - json_char * JSONWorker::RemoveWhiteSpace(const json_string & value_t){ -#endif - json_char * result; - json_char * runner = result = json_malloc<json_char>(value_t.length() + 1); //dealing with raw memory is faster than adding to a json_string - JSON_ASSERT(result, JSON_TEXT("Out of memory")); - const json_char * p = value_t.c_str(); - while(*p){ - switch(*p){ - case JSON_TEXT(' '): //defined as white space - case JSON_TEXT('\t'): //defined as white space - case JSON_TEXT('\n'): //defined as white space - case JSON_TEXT('\r'): //defined as white space - break; - case JSON_TEXT('/'): //a C comment - if (*(++p) == JSON_TEXT('*')) { //a multiline comment - COMMENT_DELIMITER(); - while ((*(++p) != JSON_TEXT('*')) || (*(p + 1) != JSON_TEXT('/'))) { - JSON_ASSERT_SAFE(*p, JSON_TEXT("Null terminator inside of a multiline quote"), COMMENT_DELIMITER(); goto endofloop;); - *runner++ = *p; - } - ++p; - COMMENT_DELIMITER(); - break; - } - //Should be a single line C comment, so let it fall through to use the bash comment stripper - JSON_ASSERT_SAFE(*p == JSON_TEXT('/'), JSON_TEXT("stray / character, not quoted, or a comment"), goto endofloop;); - case JSON_TEXT('#'): //a bash comment - SingleLineComment(p AND_RUNNER); - break; - case JSON_TEXT('\"'): //a quote - *runner++ = JSON_TEXT('\"'); - while(*(++p) != JSON_TEXT('\"')) { //find the end of the quotation, as white space is preserved within it - JSON_ASSERT_SAFE(*p, JSON_TEXT("Null terminator inside of a quotation"), goto endofloop;); - switch(*p){ - case JSON_TEXT('\\'): - *runner++ = JSON_TEXT('\\'); - *runner++ = (*++p == JSON_TEXT('\"')) ? JSON_TEXT('\1') : *p; //an escaped quote will reak havoc will all of my searching functions, so change it into an illegal character in JSON for convertion later on - break; - default: - *runner++ = *p; - break; - } - } - //no break, let it fall through so that the trailing quote gets added - default: - JSON_ASSERT_SAFE((unsigned json_char)*p >= 32, JSON_TEXT("Invalid JSON character detected (lo)"), goto endofloop;); - JSON_ASSERT_SAFE((unsigned json_char)*p <= 126, JSON_TEXT("Invalid JSON character detected (hi)"), goto endofloop;); - *runner++ = *p; - break; - } - ++p; - } - #ifdef JSON_SAFE - endofloop: - #endif - #if defined JSON_DEBUG || defined JSON_SAFE - last = *(runner - 1); - #endif - *runner = JSON_TEXT('\0'); - return result; - } - -json_string JSONWorker::RemoveWhiteSpaceAndComments(const json_string & value_t){ - json_string result; - result.reserve(value_t.length()); - const json_char * p = value_t.c_str(); - while(*p){ - switch(*p){ - case JSON_TEXT(' '): //defined as white space - case JSON_TEXT('\t'): //defined as white space - case JSON_TEXT('\n'): //defined as white space - case JSON_TEXT('\r'): //defined as white space - break; - case JSON_TEXT('/'): //a C comment - if (*(++p) == JSON_TEXT('*')) { //a multiline comment - while ((*(++p) != JSON_TEXT('*')) || (*(p + 1) != JSON_TEXT('/'))) { - JSON_ASSERT_SAFE(*p, JSON_TEXT("Null terminator inside of a multiline quote"), goto endofloop;); - } - ++p; - break; - } - //Should be a single line C comment, so let it fall through to use the bash comment stripper - JSON_ASSERT_SAFE(*p == JSON_TEXT('/'), JSON_TEXT("stray / character, not quoted, or a comment"), goto endofloop;); - case JSON_TEXT('#'): //a bash comment - SingleLineComment(p); - break; - case JSON_TEXT('\"'): //a quote - result += JSON_TEXT('\"'); - while(*(++p) != JSON_TEXT('\"')) { //find the end of the quotation, as white space is preserved within it - JSON_ASSERT(*p, JSON_TEXT("Null terminator inside of a quotation")); - switch(*p){ - case JSON_TEXT('\\'): - result += JSON_TEXT('\\'); - result += (*++p == JSON_TEXT('\"')) ? JSON_TEXT('\1') : *p; //an escaped quote will reak havoc will all of my searching functions, so change it into an illegal character in JSON for convertion later on - break; - default: - result += *p; - break; - } - } - //no break, let it fall through so that the trailing quote gets added - default: - JSON_ASSERT_SAFE((unsigned json_char)*p >= 32, JSON_TEXT("Invalid JSON character detected (lo)"), goto endofloop;); - JSON_ASSERT_SAFE((unsigned json_char)*p <= 126, JSON_TEXT("Invalid JSON character detected (hi)"), goto endofloop;); - result += *p; - break; - } - ++p; - } - #ifdef JSON_SAFE - endofloop: - #endif - return result; -} - -/* - These three functions analyze json_string literals and convert them into std::strings - This includes dealing with special characters and utf characters - */ -#ifdef JSON_UNICODE - inline unsigned json_char SurrogatePair(const unsigned json_char hi, const unsigned json_char lo){ - JSON_ASSERT(sizeof(unsigned int) == 4, JSON_TEXT("size of unsigned int is not 32-bit")); - JSON_ASSERT(sizeof(unsigned json_char) == 4, JSON_TEXT("size of json_char is not 32-bit")); - return (((hi << 10) & 0x1FFC00) + 0x10000) | lo & 0x3FF; - } - - json_string JSONWorker::UTF(const json_char * & pos){ - json_string result; - unsigned json_char first = UTF8(pos); - if ((*(pos + 1) == '\\') && (*(pos + 2) == 'u')) { - pos += 2; - unsigned json_char second = UTF8(pos); - //surrogate pair, not two characters - if ((first > 0xD800) && (first < 0xDBFF) && (second > 0xDC00) && (second < 0xDFFF)) { - result += SurrogatePair(first, second); - } else { - result += first; - result += second; - } - } else { - result += first; - } - JSON_ASSERT(!result.empty(), JSON_TEXT("missing case, somehow UTF returned empty")); - return result; - } -#endif - -unsigned json_char JSONWorker::UTF8(const json_char * & pos){ - #ifdef JSON_UNICODE - ++pos; - unsigned json_char temp = Hex(pos) << 8; - ++pos; - return temp | Hex(pos); - #else - JSON_ASSERT(*(pos + 1) == JSON_TEXT('0'), JSON_TEXT("wide utf character (hihi)")); - JSON_ASSERT(*(pos + 2) == JSON_TEXT('0'), JSON_TEXT("wide utf character (hilo)")); - pos += 3; - return Hex(pos); - #endif -} - -static char szU8Buffer[10]; - -json_char* JSONWorker::UTF8_2(const json_char * & pos){ - #ifdef JSON_UNICODE - ++pos; - unsigned json_char temp = Hex(pos) << 8; - ++pos; - *szU8Buffer= temp | Hex(pos); - szU8Buffer[1]=0; - return szU8Buffer; - #else - union { - unsigned short uChar; - unsigned char uByte[2]; - }; - pos++; - strncpy(szU8Buffer+5,pos,4); - szU8Buffer[9]=0; - uChar=strtoul(szU8Buffer+5,NULL,16); - if (uChar<0x80) { - szU8Buffer[0]=uChar; - szU8Buffer[1]=0; - } else if (uChar<0x7ff) { - szU8Buffer[0]=0xc0+(uByte[1]<<2)+(uByte[0]>>6); - szU8Buffer[1]=0x80+(uByte[0]&0x3f); - szU8Buffer[2]=0; - } else { - szU8Buffer[0]=0xe0+(uByte[1]>>4); - szU8Buffer[1]=0x80+((uByte[1]&0x0f)<<2)+(uByte[0]>>6); - szU8Buffer[2]=0x80+(uByte[0]&0x3f); - szU8Buffer[3]=0; - }
- - pos += 3; - return szU8Buffer; - #endif -} - - -json_char JSONWorker::Hex(const json_char * & pos){ - /* - takes the numeric value of the next two characters and convert them - \u0058 becomes 0x58 - - In case of \u, it's SpecialChar's responsibility to move past the first two chars - as this method is also used for \x - */ - //First character - unsigned json_char hi = *pos++ - 48; - if (hi > 48){ //A-F don't immediately follow 0-9, so have to pull them down a little - hi -= 39; - } else if (hi > 9){ //neither do a-f - hi -= 7; - } - //second character - unsigned json_char lo = *pos - 48; - if (lo > 48){ //A-F don't immediately follow 0-9, so have to pull them down a little - lo -= 39; - } else if (lo > 9){ //neither do a-f - lo -= 7; - } - //combine them - return (json_char)((hi << 4) | lo); -} - -inline json_char FromOctal(const json_char * & str){ - JSON_ASSERT(json_strlen(str) > 3, JSON_TEXT("Octal will go out of bounds")); - const unsigned json_char top = ((unsigned json_char)(*(str++) - 48)); - const unsigned json_char middle = (unsigned json_char)(*(str++) - 48); - const unsigned json_char bottom = (unsigned json_char)(*str - 48); - return (json_char)((top << 6) | (middle << 3) | bottom); -} - -void JSONWorker::SpecialChar(const json_char * & pos, json_string & res){ - /* - Since JSON uses forward slash escaping for special characters within strings, I have to - convert these escaped characters into C characters - */ - switch(*pos){ - case JSON_TEXT('\1'): //quote character (altered by RemoveWhiteSpace) - res += JSON_TEXT('\"'); - break; - case JSON_TEXT('t'): //tab character - res += JSON_TEXT('\t'); - break; - case JSON_TEXT('n'): //newline character - res += JSON_TEXT('\n'); - break; - case JSON_TEXT('r'): //return character - res += JSON_TEXT('\r'); - break; - case JSON_TEXT('\\'): //backslash - res += JSON_TEXT('\\'); - break; - case JSON_TEXT('/'): //forward slash - res += JSON_TEXT('/'); - break; - case JSON_TEXT('b'): //backspace - res += JSON_TEXT('\b'); - break; - case JSON_TEXT('f'): //formfeed - res += JSON_TEXT('\f'); - break; - case JSON_TEXT('v'): //vertical tab - res += JSON_TEXT('\v'); - break; - case JSON_TEXT('\''): //apostrophe - res += JSON_TEXT('\''); - break; - case JSON_TEXT('x'): //hexidecimal ascii code - res += Hex(++pos); - break; - case JSON_TEXT('u'): //utf character - #ifdef JSON_UNICODE - res += UTF(pos); - #else - //res += UTF8(pos); - res.append(UTF8_2(pos)); - #endif - break; - - //octal encoding - case JSON_TEXT('1'): - case JSON_TEXT('2'): - case JSON_TEXT('3'): - case JSON_TEXT('4'): - case JSON_TEXT('5'): - case JSON_TEXT('6'): - case JSON_TEXT('7'): - case JSON_TEXT('0'): - res += FromOctal(pos); - break; - - #ifdef JSON_DEBUG - default: - JSON_FAIL(JSON_TEXT("Unsupported escaped character")); - #endif - } -} - -#ifdef JSON_LESS_MEMORY - inline void doflag(const internalJSONNode * flag, bool which, bool x){ - if (which){ - flag -> _name_encoded = x; - } else { - flag -> _string_encoded = x; - } - } - - json_string JSONWorker::FixString(const json_string & value_t, const internalJSONNode * flag, bool which){ - #define setflag(x) doflag(flag, which, x) -#else - json_string JSONWorker::FixString(const json_string & value_t, bool & flag){ - #define setflag(x) flag = x -#endif - /* - Do things like unescaping - */ - setflag(false); - json_string res; - res.reserve(value_t.length()); //since it goes one character at a time, want to reserve it first so that it doens't have to reallocating - const json_char * p = value_t.c_str(); - while(*p){ - switch (*p){ - case JSON_TEXT('\\'): - setflag(true); - SpecialChar(++p, res); - break; - default: - res += *p; - break; - } - ++p; - } - return res; -} - -#ifdef JSON_UNICODE - json_string JSONWorker::toSurrogatePair(unsigned json_char C){ - JSON_ASSERT(sizeof(unsigned int) == 4, JSON_TEXT("size of unsigned int is not 32-bit")); - JSON_ASSERT(sizeof(unsigned short) == 2, JSON_TEXT("size of unsigned short is not 16-bit")); - JSON_ASSERT(sizeof(unsigned json_char) == 4, JSON_TEXT("json_char is not 32-bit")); - //Compute the high surrogate - const unsigned int U = (C >> 16) & 31; - unsigned short HiSurrogate = 0xD800 | (((unsigned short)U - 1) << 6) | ((unsigned short)C) >> 10; - - //compute the low surrogate - unsigned short LoSurrogate = (unsigned short) (0xDC00 | ((unsigned short)C) & 1023); - - json_string res; - res += toUTF8(HiSurrogate); - res += toUTF8(LoSurrogate); - return res; - } -#endif - -json_string JSONWorker::toUTF8(unsigned json_char p){ - #ifdef JSON_UNICODE - if (p > 0xFFFF) return toSurrogatePair(p); - #endif - json_string res(JSON_TEXT("\\u")); - #ifdef JSON_UNICODE - unsigned json_char hihi = ((p & 0xF000) >> 12) + 48; - if (hihi > 57) hihi += 7; //A-F don't immediately follow 0-9, so have to further adjust those - unsigned json_char hilo = ((p & 0x0F00) >> 8) + 48; - if (hilo > 57) hilo += 7; //A-F don't immediately follow 0-9, so have to further adjust those - res += hihi; - res += hilo; - unsigned json_char hi = ((p & 0x00F0) >> 4) + 48; - #else - res += JSON_TEXT("00"); - unsigned json_char hi = (p >> 4) + 48; - #endif - //convert the character to be escaped into two digits between 0 and 15 - if (hi > 57) hi += 7; //A-F don't immediately follow 0-9, so have to further adjust those - unsigned json_char lo = (p & 0x000F) + 48; - if (lo > 57) lo += 7; //A-F don't immediately follow 0-9, so have to further adjust those - res += hi; - res += lo; - return res; -} - -json_string JSONWorker::UnfixString(const json_string & value_t, bool flag){ - if (!flag) return value_t; - /* - Re-escapes a json_string so that it can be written out into a JSON file - */ - json_string res; - res.reserve(value_t.length()); //since it goes one character at a time, want to reserve it first so that it doens't have to reallocating - const json_char * p = value_t.c_str(); - while(*p){ - switch(*p){ - case JSON_TEXT('\"'): //quote character - res += JSON_TEXT("\\\""); - break; - case JSON_TEXT('\t'): //tab character - res += JSON_TEXT("\\t"); - break; - case JSON_TEXT('\n'): //newline character - res += JSON_TEXT("\\n"); - break; - case JSON_TEXT('\r'): //return character - res += JSON_TEXT("\\r"); - break; - case JSON_TEXT('\\'): //backslash - res += JSON_TEXT("\\\\"); - break; - case JSON_TEXT('/'): //forward slash - res += JSON_TEXT("\\/"); - break; - case JSON_TEXT('\b'): //backspace - res += JSON_TEXT("\\b"); - break; - case JSON_TEXT('\f'): //formfeed - res += JSON_TEXT("\\f"); - break; - case JSON_TEXT('\v'): //vertical tab - res += JSON_TEXT("\\v"); - break; - case JSON_TEXT('\''): //apostrophe - res += JSON_TEXT("\\\'"); - break; - default: - /*if (((unsigned json_char)(*p) < 32) || ((unsigned json_char)(*p) > 126)) { - //res += toUTF8((unsigned json_char)(*p)); - } else*/ { - res += *p; - } - break; - } - ++p; - } - return res; -} - - -//Create a childnode -#ifdef JSON_COMMENTS - #define ARRAY_PARAM bool array //Just to supress warnings -#else - #define ARRAY_PARAM bool -#endif -inline void JSONWorker::NewNode(const internalJSONNode * parent, const json_string & name, const json_string & value, ARRAY_PARAM){ - #ifdef JSON_COMMENTS - const json_char * runner = (array) ? value.c_str() : name.c_str(); - json_string _comment; - if (*runner == '\5') { //multiple comments will be consolidated into one - newcomment: - while(*(++runner) != '\5') { - JSON_ASSERT(*runner, JSON_TEXT("Removing white space failed")); - _comment += *runner; - } - if (*(++runner) == '\5') { //step past the trailing tag - _comment += '\n'; - goto newcomment; - } - } - internalJSONNode * myinternal; - if (array){ - myinternal = internalJSONNode::newInternal(name, runner); - } else { - myinternal = internalJSONNode::newInternal(++runner, value); - } - JSONNode * child = JSONNode::newJSONNode(myinternal); - child -> set_comment(_comment); - const_cast<internalJSONNode*>(parent) -> Children.push_back(child); //attach it to the parent node - #else - const_cast<internalJSONNode*>(parent) -> Children.push_back(JSONNode::newJSONNode(internalJSONNode::newInternal(name.c_str() + 1, value))); //attach it to the parent node - #endif -} - -//Create a subarray -void JSONWorker::DoArray(const internalJSONNode * parent, const json_string & value_t){ - /* - This takes an array and creates nodes out of them - */ - JSON_ASSERT(!value_t.empty(), JSON_TEXT("DoArray is empty")); - JSON_ASSERT_SAFE(value_t[0] == JSON_TEXT('['), JSON_TEXT("DoArray is not an array"), parent -> Nullify(); return;); - const size_t len = value_t.length(); - if (len <= 2) return; // just a [] (blank array) - - //Not sure what's in the array, so we have to use commas - size_t starting = 1; //ignore the [ - size_t ending = FindNextRelevant(JSON_TEXT(','), value_t, 1); - while (ending != json_string::npos){ - #ifdef JSON_SAFE - json_string newValue = value_t.substr(starting, ending - starting); - JSON_ASSERT_SAFE(FindNextRelevant(JSON_TEXT(':'), newValue, 0) == json_string::npos, JSON_TEXT("Key/Value pairs are not allowed in arrays"), parent -> Nullify(); return;); - NewNode(parent, JSON_TEXT(""), newValue, true); - #else - NewNode(parent, JSON_TEXT(""), value_t.substr(starting, ending - starting), true); - #endif - starting = ending + 1; - ending = FindNextRelevant(JSON_TEXT(','), value_t, starting); - } - //since the last one will not find the comma, we have to add it here, but ignore the final ] - - #ifdef JSON_SAFE - json_string newValue = value_t.substr(starting, len - starting - 1); - JSON_ASSERT_SAFE(FindNextRelevant(JSON_TEXT(':'), newValue, 0) == json_string::npos, JSON_TEXT("Key/Value pairs are not allowed in arrays"), parent -> Nullify(); return;); - NewNode(parent, JSON_TEXT(""), newValue, true); - #else - NewNode(parent, JSON_TEXT(""), value_t.substr(starting, len - starting - 1), true); - #endif -} - - -//Create all child nodes -void JSONWorker::DoNode(const internalJSONNode * parent, const json_string & value_t){ - /* - This take a node and creates its members and such - */ - JSON_ASSERT(!value_t.empty(), JSON_TEXT("DoNode is empty")); - JSON_ASSERT_SAFE(value_t[0] == JSON_TEXT('{'), JSON_TEXT("DoNode is not an node"), parent -> Nullify(); return;); - const size_t len = value_t.length(); - if (len <= 2) return; // just a {} (blank node) - - size_t name_starting = 1; //ignore the { - size_t name_ending = FindNextRelevant(JSON_TEXT(':'), value_t, 1); //find where the name ends - JSON_ASSERT_SAFE(name_ending != json_string::npos, JSON_TEXT("Missing :"), parent -> Nullify(); return;); - json_string name = value_t.substr(name_starting, name_ending - 2); //pull the name out - size_t value_ending = FindNextRelevant(JSON_TEXT(','), value_t, name_ending); //find the end of the value - while (value_ending != json_string::npos){ - NewNode(parent, name, value_t.substr(name_ending + 1, value_ending - name_ending - 1), false); - name_starting = value_ending + 1; - name_ending = FindNextRelevant(JSON_TEXT(':'), value_t, name_starting); - JSON_ASSERT_SAFE(name_ending != json_string::npos, JSON_TEXT("Missing :"), parent -> Nullify(); return;); - name = value_t.substr(name_starting, name_ending - name_starting - 1); - value_ending = FindNextRelevant(JSON_TEXT(','), value_t, name_ending); - } - //since the last one will not find the comma, we have to add it here - NewNode(parent, name, value_t.substr(name_ending + 1, len - name_ending - 2), false); -} |