X-Git-Url: http://review.tizen.org/git/?p=platform%2Fcore%2Fuifw%2Fdali-toolkit.git;a=blobdiff_plain;f=dali-toolkit%2Finternal%2Fbuilder%2Fjson-parser-state.cpp;h=636bac17cb576252ef6178438adde31b7dac3479;hp=3691838345bd18ed8e69424342531acaff1f488d;hb=HEAD;hpb=8e3247866b55d0a5fbc361169eec6d40228e4fdf diff --git a/dali-toolkit/internal/builder/json-parser-state.cpp b/dali-toolkit/internal/builder/json-parser-state.cpp index 3691838..3262a81 100644 --- a/dali-toolkit/internal/builder/json-parser-state.cpp +++ b/dali-toolkit/internal/builder/json-parser-state.cpp @@ -20,19 +20,16 @@ // EXTERNAL INCLUDES #include +#include namespace Dali { - namespace Toolkit { - namespace Internal { - namespace { - // true if character represent a digit inline bool IsDigit(char c) { @@ -40,30 +37,30 @@ inline bool IsDigit(char c) } // convert string to integer -bool StringToInteger(const char *first, const char *last, int& out) +bool StringToInteger(const char* first, const char* last, int& out) { int sign = 1; - if (first != last) + if(first != last) { - if (*first == '-') + if(*first == '-') { sign = -1; ++first; } - else if (*first == '+') + else if(*first == '+') { ++first; } } // json error for int starting with zero - if( 0 == (*first - '0') && (first+1 != last)) + if(0 == (*first - '0') && (first + 1 != last)) { return false; } int result = 0; - for (; first != last && IsDigit(*first); ++first) + for(; first != last && IsDigit(*first); ++first) { result = 10 * result + (*first - '0'); } @@ -80,21 +77,21 @@ bool StringToInteger(const char *first, const char *last, int& out) } // convert hexadecimal string to unsigned integer -bool HexStringToUnsignedInteger(const char *first, const char *last, unsigned int& out) +bool HexStringToUnsignedInteger(const char* first, const char* last, unsigned int& out) { unsigned int result = 0; - for (; first != last; ++first) + for(; first != last; ++first) { int digit; - if (IsDigit(*first)) + if(IsDigit(*first)) { digit = *first - '0'; } - else if (*first >= 'a' && *first <= 'f') + else if(*first >= 'a' && *first <= 'f') { digit = *first - 'a' + 10; } - else if (*first >= 'A' && *first <= 'F') + else if(*first >= 'A' && *first <= 'F') { digit = *first - 'A' + 10; } @@ -121,14 +118,14 @@ bool StringToFloat(const char* first, const char* last, float& out) { // sign float sign = 1; - if (first != last) + if(first != last) { - if (*first == '-') + if(*first == '-') { sign = -1; ++first; } - else if (*first == '+') + else if(*first == '+') { ++first; } @@ -136,18 +133,18 @@ bool StringToFloat(const char* first, const char* last, float& out) // integer part float result = 0; - for (; first != last && IsDigit(*first); ++first) + for(; first != last && IsDigit(*first); ++first) { result = 10 * result + (*first - '0'); } // fraction part - if (first != last && *first == '.') + if(first != last && *first == '.') { ++first; float inv_base = 0.1f; - for (; first != last && IsDigit(*first); ++first) + for(; first != last && IsDigit(*first); ++first) { result += (*first - '0') * inv_base; inv_base *= 0.1f; @@ -159,17 +156,17 @@ bool StringToFloat(const char* first, const char* last, float& out) // exponent bool exponent_negative = false; - int exponent = 0; - if (first != last && (*first == 'e' || *first == 'E')) + int exponent = 0; + if(first != last && (*first == 'e' || *first == 'E')) { ++first; - if (*first == '-') + if(*first == '-') { exponent_negative = true; ++first; } - else if (*first == '+') + else if(*first == '+') { ++first; } @@ -179,21 +176,21 @@ bool StringToFloat(const char* first, const char* last, float& out) return false; } - for (; first != last && IsDigit(*first); ++first) + for(; first != last && IsDigit(*first); ++first) { exponent = 10 * exponent + (*first - '0'); } } - if (exponent) + if(exponent) { float power_of_ten = 10; - for (; exponent > 1; exponent--) + for(; exponent > 1; exponent--) { power_of_ten *= 10; } - if (exponent_negative) + if(exponent_negative) { result /= power_of_ten; } @@ -215,11 +212,10 @@ bool StringToFloat(const char* first, const char* last, float& out) } } - bool IsNumber(char c) { bool ret = false; - switch( c ) + switch(c) { case '0': case '1': @@ -243,16 +239,21 @@ bool IsNumber(char c) return ret; } -} // anon namespace - +} // namespace JsonParserState::JsonParserState(TreeNode* _root) - : mRoot(_root), mCurrent(_root), - mErrorDescription(NULL), mErrorNewLine(0), mErrorColumn(0), mErrorPosition(0), - mNumberOfParsedChars(0), mNumberOfCreatedNodes(0), mFirstParse(false), - mState(STATE_START) +: mRoot(_root), + mCurrent(_root), + mErrorDescription(nullptr), + mErrorNewLine(0), + mErrorColumn(0), + mErrorPosition(0), + mNumberOfParsedChars(0), + mNumberOfCreatedNodes(0), + mFirstParse(false), + mState(STATE_START) { - if(_root == NULL) + if(_root == nullptr) { mFirstParse = true; } @@ -260,13 +261,13 @@ JsonParserState::JsonParserState(TreeNode* _root) TreeNode* JsonParserState::CreateNewNode(const char* name, TreeNode::NodeType type) { - TreeNode* node = NULL; + TreeNode* node = nullptr; node = TreeNodeManipulator::NewTreeNode(); TreeNodeManipulator modifyNew(node); modifyNew.SetType(type); modifyNew.SetName(name); - if(mRoot == NULL) + if(mRoot == nullptr) { mRoot = node; mCurrent = TreeNodeManipulator(mRoot); @@ -280,12 +281,11 @@ TreeNode* JsonParserState::CreateNewNode(const char* name, TreeNode::NodeType ty ++mNumberOfCreatedNodes; return node; - } TreeNode* JsonParserState::NewNode(const char* name, TreeNode::NodeType type) { - TreeNode* node = NULL; + TreeNode* node = nullptr; if(mFirstParse) { @@ -298,7 +298,7 @@ TreeNode* JsonParserState::NewNode(const char* name, TreeNode::NodeType type) if(name) { const TreeNode* found = mCurrent.GetChild(name); - if( NULL != found ) + if(nullptr != found) { node = const_cast(found); } @@ -306,7 +306,7 @@ TreeNode* JsonParserState::NewNode(const char* name, TreeNode::NodeType type) else { // if root node - if( mCurrent.GetParent() == NULL ) + if(mCurrent.GetParent() == nullptr) { node = mRoot; } @@ -355,7 +355,7 @@ bool JsonParserState::ParseWhiteSpace() bool c_comment = false; bool cpp_comment = false; - if( mIter == mEnd ) + if(mIter == mEnd) { return true; } @@ -371,7 +371,7 @@ bool JsonParserState::ParseWhiteSpace() NewLine(); } - if( AtLeast(2) ) + if(AtLeast(2)) { nextChar = mIter[1]; } @@ -380,43 +380,43 @@ bool JsonParserState::ParseWhiteSpace() nextChar = 0; } - if( cpp_comment ) + if(cpp_comment) { - if( '\n' == c ) + if('\n' == c) { cpp_comment = false; Advance(1); continue; // rather than carry on as comments may be back to back } } - else if( !c_comment && (c == '/' && nextChar == '/') ) + else if(!c_comment && (c == '/' && nextChar == '/')) { cpp_comment = true; } - if( c_comment ) + if(c_comment) { - if( c == '*' && nextChar == '/' ) + if(c == '*' && nextChar == '/') { c_comment = false; Advance(2); continue; } } - else if( !cpp_comment && (c == '/' && nextChar == '*') ) + else if(!cpp_comment && (c == '/' && nextChar == '*')) { c_comment = true; } - if( ! (c_comment || cpp_comment) ) + if(!(c_comment || cpp_comment)) { - if( ! (c == '\x20' || c == '\x9' || c == '\xD' || c == '\xA' ) ) + if(!(c == '\x20' || c == '\x9' || c == '\xD' || c == '\xA')) { break; } } - if( AdvanceEnded(1) ) + if(AdvanceEnded(1)) { break; } @@ -428,9 +428,9 @@ bool JsonParserState::ParseWhiteSpace() bool JsonParserState::ParseSymbol(const std::string& symbol) { - if( AtLeast( symbol.size() ) ) + if(AtLeast(symbol.size())) { - for(int i = 0; i < static_cast( symbol.size() ); ++i) + for(int i = 0; i < static_cast(symbol.size()); ++i) { if(*mIter != symbol[i]) { @@ -448,7 +448,7 @@ bool JsonParserState::ParseSymbol(const std::string& symbol) bool JsonParserState::ParseTrue() { - if( ParseSymbol("true") ) + if(ParseSymbol("true")) { mCurrent.SetInteger(1); mCurrent.SetType(TreeNode::BOOLEAN); @@ -462,7 +462,7 @@ bool JsonParserState::ParseTrue() bool JsonParserState::ParseFalse() { - if( ParseSymbol("false") ) + if(ParseSymbol("false")) { mCurrent.SetInteger(0); mCurrent.SetType(TreeNode::BOOLEAN); @@ -476,7 +476,7 @@ bool JsonParserState::ParseFalse() bool JsonParserState::ParseNULL() { - if( ParseSymbol("null") ) + if(ParseSymbol("null")) { mCurrent.SetType(TreeNode::IS_NULL); return true; @@ -489,30 +489,30 @@ bool JsonParserState::ParseNULL() bool JsonParserState::ParseNumber() { - mCurrent.SetType( TreeNode::INTEGER ); + mCurrent.SetType(TreeNode::INTEGER); VectorCharIter first = mIter; - char c = Char(); + char c = Char(); - if( !(c == '-' || IsNumber(c) ) ) + if(!(c == '-' || IsNumber(c))) { return Error("Number must start with '-' or 0-9"); } - while ( IsNumber(c) || c == '.' || c == 'e' || c == 'E' || c == '+' || c == '-' ) + while(IsNumber(c) || c == '.' || c == 'e' || c == 'E' || c == '+' || c == '-') { - if (c == '.' || c == 'e' || c == 'E') + if(c == '.' || c == 'e' || c == 'E') { - mCurrent.SetType( TreeNode::FLOAT ); + mCurrent.SetType(TreeNode::FLOAT); } Advance(1); c = Char(); } - if( mCurrent.GetType() == TreeNode::INTEGER ) + if(mCurrent.GetType() == TreeNode::INTEGER) { int i = 0; - if( StringToInteger(&(*first), &(*mIter), i ) ) + if(StringToInteger(&(*first), &(*mIter), i)) { mCurrent.SetInteger(i); } @@ -525,7 +525,7 @@ bool JsonParserState::ParseNumber() if(mCurrent.GetType() == TreeNode::FLOAT) { float f = 0.f; - if( StringToFloat(&(*first), &(*mIter), f) ) + if(StringToFloat(&(*first), &(*mIter), f)) { mCurrent.SetFloat(f); } @@ -535,25 +535,25 @@ bool JsonParserState::ParseNumber() } } - return (mCurrent.GetType() == TreeNode::INTEGER) || (mCurrent.GetType() == TreeNode::FLOAT); + return (mCurrent.GetType() == TreeNode::INTEGER) || (mCurrent.GetType() == TreeNode::FLOAT); } char* JsonParserState::EncodeString() { - int substitution = 0; - VectorCharIter first = mIter; - VectorCharIter last = mIter; + int substitution = 0; + VectorCharIter first = mIter; + VectorCharIter last = mIter; - while (*mIter) + while(*mIter) { - if (static_cast(*mIter) < '\x20') + if(static_cast(*mIter) < '\x20') { - static_cast( Error("Control characters not allowed in strings") ); - return NULL; + static_cast(Error("Control characters not allowed in strings")); + return nullptr; } - else if (*mIter == '\\' && AtLeast(2)) + else if(*mIter == '\\' && AtLeast(2)) { - switch (*(mIter+1)) + switch(*(mIter + 1)) { case '"': { @@ -598,31 +598,31 @@ char* JsonParserState::EncodeString() case 'u': { unsigned int codepoint; - if( !AtLeast(6) ) + if(!AtLeast(6)) { - static_cast( Error("Bad unicode codepoint; not enough characters") ); - return NULL; + static_cast(Error("Bad unicode codepoint; not enough characters")); + return nullptr; } - if ( !HexStringToUnsignedInteger(&(*(mIter + 2)), &(*(mIter + 6)), codepoint) ) + if(!HexStringToUnsignedInteger(&(*(mIter + 2)), &(*(mIter + 6)), codepoint)) { - static_cast( Error("Bad unicode codepoint") ); - return NULL; + static_cast(Error("Bad unicode codepoint")); + return nullptr; } - if (codepoint <= 0x7F) + if(codepoint <= 0x7F) { *last = (char)codepoint; } - else if (codepoint <= 0x7FF) + else if(codepoint <= 0x7FF) { *last++ = (char)(0xC0 | (codepoint >> 6)); - *last = (char)(0x80 | (codepoint & 0x3F)); + *last = (char)(0x80 | (codepoint & 0x3F)); } - else if (codepoint <= 0xFFFF) + else if(codepoint <= 0xFFFF) { *last++ = (char)(0xE0 | (codepoint >> 12)); *last++ = (char)(0x80 | ((codepoint >> 6) & 0x3F)); - *last = (char)(0x80 | (codepoint & 0x3F)); + *last = (char)(0x80 | (codepoint & 0x3F)); } Advance(4); @@ -631,15 +631,15 @@ char* JsonParserState::EncodeString() default: { - static_cast( Error("Unrecognized escape sequence") ); - return NULL; + static_cast(Error("Unrecognized escape sequence")); + return nullptr; } } ++last; Advance(2); } - else if (*mIter == '{') + else if(*mIter == '{') { if((0 == substitution) && (*last != '\\')) { @@ -648,7 +648,7 @@ char* JsonParserState::EncodeString() *last++ = *mIter; Advance(1); } - else if (*mIter == '}') + else if(*mIter == '}') { if(substitution) { @@ -657,7 +657,7 @@ char* JsonParserState::EncodeString() *last++ = *mIter; Advance(1); } - else if (*mIter == '"') + else if(*mIter == '"') { *last = 0; Advance(1); @@ -672,20 +672,186 @@ char* JsonParserState::EncodeString() } // while(*mIter) mNumberOfParsedChars += last - first; - mNumberOfParsedChars += 1 ; // null terminator + mNumberOfParsedChars += 1; // null terminator - mCurrent.SetSubstitution( substitution > 1 ); + mCurrent.SetSubstitution(substitution > 1); // return true; return &(*first); } // ParseString() +bool JsonParserState::HandleStartState(const char* name, const char currentChar) +{ + if('{' == currentChar) + { + NewNode(name, TreeNode::OBJECT); + mState = STATE_OBJECT; + } + else if('[' == currentChar) + { + NewNode(name, TreeNode::ARRAY); + mState = STATE_VALUE; + } + else + { + return Error("Json must start with object {} or array []"); + } + + AdvanceSkipWhiteSpace(1); + return true; +} + +bool JsonParserState::HandleObjectState(const char currentChar, const char lastCharacter) +{ + if('}' == currentChar) + { + if(',' == lastCharacter) + { + return Error("Unexpected comma"); + } + + if(!UpToParent()) + { + return false; + } + mState = STATE_VALUE; + } + else if('"' == currentChar) + { + mState = STATE_KEY; + } + else + { + return Error("Unexpected character"); + } + + AdvanceSkipWhiteSpace(1); + return true; +} + +bool JsonParserState::HandleKeyState(char*& name) +{ + name = EncodeString(); + if(nullptr == name) + { + return false; + } + if(!ParseWhiteSpace()) + { + return false; + } + if(':' != Char()) + { + return Error("Expected ':'"); + } + if(!ParseWhiteSpace()) + { + return false; + } + mState = STATE_VALUE; + + AdvanceSkipWhiteSpace(1); + return true; +} + +bool JsonParserState::HandleCharacterQuote(char*& name) +{ + Advance(1); + NewNode(name, TreeNode::STRING); + if(char* value = EncodeString()) + { + mCurrent.SetString(value); + } + else + { + return false; + } + if(!UpToParent()) + { + return false; + } + AdvanceSkipWhiteSpace(0); + return true; +} + +bool JsonParserState::HandleCharacterNumberOrHyphen(const char* name) +{ + NewNode(name, TreeNode::IS_NULL); + if(!ParseNumber()) + { + return false; + } + if(!UpToParent()) + { + return false; + } + AdvanceSkipWhiteSpace(0); + return true; +} + +bool JsonParserState::HandleValueState(char*& name, const char currentChar, const char lastCharacter) +{ + bool handled = true; + + if('"' == currentChar) + { + handled = HandleCharacterQuote(name); + } + else if(IsNumber(currentChar) || currentChar == '-') + { + handled = HandleCharacterNumberOrHyphen(name); + } + else if('{' == currentChar) + { + handled = HandleCharacterBracesStart(name, lastCharacter); + } + else if('}' == currentChar) + { + handled = HandleCharacterBracesEnd(lastCharacter); + } + else if('[' == currentChar) + { + handled = HandleCharacterSquareBracketStart(name); + } + else if(']' == currentChar) + { + handled = HandleCharacterSquareBracketEnd(lastCharacter); + } + else if('t' == currentChar) + { + handled = HandleCharacterLowercaseT(name); + } + else if('n' == currentChar) + { + handled = HandleCharacterLowercaseN(name); + } + else if('f' == currentChar) + { + handled = HandleCharacterLowercaseF(name); + } + else if(',' == currentChar) + { + handled = HandleCharacterComma(name); + } + else + { + handled = Error("Unexpected character"); + } + + if(handled) + { + name = nullptr; + } + + return handled; +} + bool JsonParserState::ParseJson(VectorChar& source) { Reset(); - if( 0 == source.size() ) + if(0 == source.size()) { return Error("Empty source buffer to parse"); } @@ -693,11 +859,11 @@ bool JsonParserState::ParseJson(VectorChar& source) mIter = source.begin(); mEnd = source.end(); - char* name = NULL; - char currentChar = 0; - char lastCharacter = 0; + char* name = nullptr; + char currentChar = 0; + char lastCharacter = 0; - if( !ParseWhiteSpace() ) + if(!ParseWhiteSpace()) { return false; } @@ -705,250 +871,40 @@ bool JsonParserState::ParseJson(VectorChar& source) while(mIter != mEnd) { lastCharacter = currentChar; - currentChar = Char(); + currentChar = Char(); - switch( mState ) + switch(mState) { case STATE_START: { - if( '{' == currentChar ) - { - NewNode(name, TreeNode::OBJECT); - mState = STATE_OBJECT; - } - else if( '[' == currentChar ) + if(!HandleStartState(name, currentChar)) { - NewNode(name, TreeNode::ARRAY); - mState = STATE_VALUE; - } - else - { - return Error("Json must start with object {} or array []"); + return false; } - - AdvanceSkipWhiteSpace(1); break; } case STATE_OBJECT: { - if( '}' == currentChar ) + if(!HandleObjectState(currentChar, lastCharacter)) { - if(',' == lastCharacter) - { - return Error("Unexpected comma"); - } - - if( !UpToParent() ) - { - return false; - } - mState = STATE_VALUE; - } - else if ( '"' == currentChar ) - { - mState = STATE_KEY; - } - else - { - return Error("Unexpected character"); + return false; } - - AdvanceSkipWhiteSpace(1); break; } case STATE_KEY: { - name = EncodeString(); - if( NULL == name ) - { - return false; - } - if( !ParseWhiteSpace() ) - { - return false; - } - if( ':' != Char()) - { - return Error("Expected ':'"); - } - if( !ParseWhiteSpace() ) + if(!HandleKeyState(name)) { return false; } - mState = STATE_VALUE; - - AdvanceSkipWhiteSpace(1); break; } case STATE_VALUE: { - if( '"' == currentChar ) - { - Advance(1); - NewNode(name, TreeNode::STRING); - if( char* value = EncodeString() ) - { - mCurrent.SetString(value); - } - else - { - return false; - } - if( !UpToParent() ) - { - return false; - } - AdvanceSkipWhiteSpace(0); - } - else if( IsNumber(currentChar) || currentChar == '-' ) + if(!HandleValueState(name, currentChar, lastCharacter)) { - NewNode(name, TreeNode::IS_NULL); - if( !ParseNumber() ) - { - return false; - } - if( !UpToParent() ) - { - return false; - } - AdvanceSkipWhiteSpace(0); - } - else if( '{' == currentChar ) - { - if( '}' == lastCharacter ) - { - return Error("Expected a comma"); - } - else - { - NewNode(name, TreeNode::OBJECT); - mState = STATE_OBJECT; - AdvanceSkipWhiteSpace(1); - } - } - else if( '}' == currentChar ) - { - if(',' == lastCharacter) - { - return Error("Expected another value"); - } - - if(mCurrent.GetType() != TreeNode::OBJECT) - { - return Error("Mismatched array definition"); - } - - if(mCurrent.GetParent() == NULL) - { - mState = STATE_END; - } - else - { - if( !UpToParent() ) - { - return false; - } - } - AdvanceSkipWhiteSpace(1); - } - else if( '[' == currentChar ) - { - NewNode(name, TreeNode::ARRAY); - mState = STATE_VALUE; - AdvanceSkipWhiteSpace(1); - } - else if( ']' == currentChar ) - { - if(',' == lastCharacter) - { - return Error("Expected a value"); - } - - if(mCurrent.GetType() != TreeNode::ARRAY) - { - return Error("Mismatched braces in object definition"); - } - - if(mCurrent.GetParent() == NULL) - { - mState = STATE_END; - } - else - { - if( !UpToParent() ) - { - return false; - } - } - AdvanceSkipWhiteSpace(1); - } - else if( 't' == currentChar ) - { - NewNode(name, TreeNode::BOOLEAN); - if( !ParseTrue() ) - { - return false; - } - if( !UpToParent() ) - { - return false; - } - AdvanceSkipWhiteSpace(0); - } - else if( 'n' == currentChar ) - { - NewNode(name, TreeNode::IS_NULL); - if( !ParseNULL() ) - { - return false; - } - if( !UpToParent() ) - { - return false; - } - AdvanceSkipWhiteSpace(0); - } - else if( 'f' == currentChar) - { - NewNode(name, TreeNode::BOOLEAN); - if( !ParseFalse() ) - { - return false; - } - if( !UpToParent() ) - { - return false; - } - AdvanceSkipWhiteSpace(0); - } - else if( ',' == currentChar ) - { - if( 0 == mCurrent.Size() ) - { - return Error("Missing Value"); - } - - if(mCurrent.GetType() == TreeNode::OBJECT) - { - mState = STATE_OBJECT; // to get '"' in '"key":val' - } - else if(mCurrent.GetType() == TreeNode::ARRAY) - { - mState = STATE_VALUE; // array so just get next value - } - else - { - return Error("Unexpected character"); - } - AdvanceSkipWhiteSpace(1); - } - else - { - return Error("Unexpected character"); + return false; } - - name = NULL; - break; } // case STATE_VALUE case STATE_END: @@ -961,7 +917,7 @@ bool JsonParserState::ParseJson(VectorChar& source) } // while(1) // - if( mState != STATE_END ) + if(mState != STATE_END) { return Error("Unexpected termination character"); } @@ -972,17 +928,160 @@ bool JsonParserState::ParseJson(VectorChar& source) } // ParseJson - void JsonParserState::Reset() { mCurrent = TreeNodeManipulator(mRoot); - mErrorDescription = NULL; - mErrorNewLine = 0; - mErrorColumn = 0; - mErrorPosition = 0; + mErrorDescription = nullptr; + mErrorNewLine = 0; + mErrorColumn = 0; + mErrorPosition = 0; } +bool JsonParserState::HandleCharacterBracesStart(const char* name, const char lastCharacter) +{ + if('}' == lastCharacter) + { + return Error("Expected a comma"); + } + else + { + NewNode(name, TreeNode::OBJECT); + mState = STATE_OBJECT; + AdvanceSkipWhiteSpace(1); + } + return true; +} + +bool JsonParserState::HandleCharacterBracesEnd(const char lastCharacter) +{ + if(',' == lastCharacter) + { + return Error("Expected another value"); + } + + if(mCurrent.GetType() != TreeNode::OBJECT) + { + return Error("Mismatched array definition"); + } + + if(mCurrent.GetParent() == nullptr) + { + mState = STATE_END; + } + else + { + if(!UpToParent()) + { + return false; + } + } + AdvanceSkipWhiteSpace(1); + return true; +} + +bool JsonParserState::HandleCharacterSquareBracketStart(const char* name) +{ + NewNode(name, TreeNode::ARRAY); + mState = STATE_VALUE; + AdvanceSkipWhiteSpace(1); + return true; +} + +bool JsonParserState::HandleCharacterSquareBracketEnd(const char lastCharacter) +{ + if(',' == lastCharacter) + { + return Error("Expected a value"); + } + + if(mCurrent.GetType() != TreeNode::ARRAY) + { + return Error("Mismatched braces in object definition"); + } + + if(mCurrent.GetParent() == nullptr) + { + mState = STATE_END; + } + else + { + if(!UpToParent()) + { + return false; + } + } + AdvanceSkipWhiteSpace(1); + return true; +} + +bool JsonParserState::HandleCharacterLowercaseT(const char* name) +{ + NewNode(name, TreeNode::BOOLEAN); + if(!ParseTrue()) + { + return false; + } + if(!UpToParent()) + { + return false; + } + AdvanceSkipWhiteSpace(0); + return true; +} + +bool JsonParserState::HandleCharacterLowercaseN(const char* name) +{ + NewNode(name, TreeNode::IS_NULL); + if(!ParseNULL()) + { + return false; + } + if(!UpToParent()) + { + return false; + } + AdvanceSkipWhiteSpace(0); + return true; +} + +bool JsonParserState::HandleCharacterLowercaseF(const char* name) +{ + NewNode(name, TreeNode::BOOLEAN); + if(!ParseFalse()) + { + return false; + } + if(!UpToParent()) + { + return false; + } + AdvanceSkipWhiteSpace(0); + return true; +} + +bool JsonParserState::HandleCharacterComma(const char* name) +{ + if(0 == mCurrent.Size()) + { + return Error("Missing Value"); + } + + if(mCurrent.GetType() == TreeNode::OBJECT) + { + mState = STATE_OBJECT; // to get '"' in '"key":val' + } + else if(mCurrent.GetType() == TreeNode::ARRAY) + { + mState = STATE_VALUE; // array so just get next value + } + else + { + return Error("Unexpected character"); + } + AdvanceSkipWhiteSpace(1); + return true; +} } // namespace Internal