+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;
+}
+