#include <dali-toolkit/internal/builder/json-parser-state.h>
// EXTERNAL INCLUDES
-#include <string>
#include <algorithm>
+#include <string>
namespace Dali
{
-
namespace Toolkit
{
-
namespace Internal
{
-
namespace
{
-
// true if character represent a digit
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');
}
}
// 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;
}
{
// sign
float sign = 1;
- if (first != last)
+ if(first != last)
{
- if (*first == '-')
+ if(*first == '-')
{
sign = -1;
++first;
}
- else if (*first == '+')
+ else if(*first == '+')
{
++first;
}
// 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;
// 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;
}
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;
}
}
}
-
bool IsNumber(char c)
{
bool ret = false;
- switch( c )
+ switch(c)
{
case '0':
case '1':
return ret;
}
-} // anon namespace
-
+} // namespace
JsonParserState::JsonParserState(TreeNode* _root)
- : mRoot(_root), mCurrent(_root),
- mErrorDescription(nullptr), 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 == nullptr)
{
++mNumberOfCreatedNodes;
return node;
-
}
TreeNode* JsonParserState::NewNode(const char* name, TreeNode::NodeType type)
if(name)
{
const TreeNode* found = mCurrent.GetChild(name);
- if( nullptr != found )
+ if(nullptr != found)
{
node = const_cast<TreeNode*>(found);
}
else
{
// if root node
- if( mCurrent.GetParent() == nullptr )
+ if(mCurrent.GetParent() == nullptr)
{
node = mRoot;
}
bool c_comment = false;
bool cpp_comment = false;
- if( mIter == mEnd )
+ if(mIter == mEnd)
{
return true;
}
NewLine();
}
- if( AtLeast(2) )
+ if(AtLeast(2))
{
nextChar = mIter[1];
}
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;
}
bool JsonParserState::ParseSymbol(const std::string& symbol)
{
- if( AtLeast( symbol.size() ) )
+ if(AtLeast(symbol.size()))
{
- for(int i = 0; i < static_cast<int>( symbol.size() ); ++i)
+ for(int i = 0; i < static_cast<int>(symbol.size()); ++i)
{
if(*mIter != symbol[i])
{
bool JsonParserState::ParseTrue()
{
- if( ParseSymbol("true") )
+ if(ParseSymbol("true"))
{
mCurrent.SetInteger(1);
mCurrent.SetType(TreeNode::BOOLEAN);
bool JsonParserState::ParseFalse()
{
- if( ParseSymbol("false") )
+ if(ParseSymbol("false"))
{
mCurrent.SetInteger(0);
mCurrent.SetType(TreeNode::BOOLEAN);
bool JsonParserState::ParseNULL()
{
- if( ParseSymbol("null") )
+ if(ParseSymbol("null"))
{
mCurrent.SetType(TreeNode::IS_NULL);
return true;
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);
}
if(mCurrent.GetType() == TreeNode::FLOAT)
{
float f = 0.f;
- if( StringToFloat(&(*first), &(*mIter), f) )
+ if(StringToFloat(&(*first), &(*mIter), f))
{
mCurrent.SetFloat(f);
}
}
}
- 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<unsigned char>(*mIter) < '\x20')
+ if(static_cast<unsigned char>(*mIter) < '\x20')
{
- static_cast<void>( Error("Control characters not allowed in strings") );
+ static_cast<void>(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 '"':
{
case 'u':
{
unsigned int codepoint;
- if( !AtLeast(6) )
+ if(!AtLeast(6))
{
- static_cast<void>( Error("Bad unicode codepoint; not enough characters") );
+ static_cast<void>(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<void>( Error("Bad unicode codepoint") );
+ static_cast<void>(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);
default:
{
- static_cast<void>( Error("Unrecognized escape sequence") );
+ static_cast<void>(Error("Unrecognized escape sequence"));
return nullptr;
}
}
++last;
Advance(2);
}
- else if (*mIter == '{')
+ else if(*mIter == '{')
{
if((0 == substitution) && (*last != '\\'))
{
*last++ = *mIter;
Advance(1);
}
- else if (*mIter == '}')
+ else if(*mIter == '}')
{
if(substitution)
{
*last++ = *mIter;
Advance(1);
}
- else if (*mIter == '"')
+ else if(*mIter == '"')
{
*last = 0;
Advance(1);
} // 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);
bool JsonParserState::HandleStartState(const char* name, const char currentChar)
{
- if( '{' == currentChar )
+ if('{' == currentChar)
{
NewNode(name, TreeNode::OBJECT);
mState = STATE_OBJECT;
}
- else if( '[' == currentChar )
+ else if('[' == currentChar)
{
NewNode(name, TreeNode::ARRAY);
mState = STATE_VALUE;
bool JsonParserState::HandleObjectState(const char currentChar, const char lastCharacter)
{
- if( '}' == currentChar )
+ if('}' == currentChar)
{
if(',' == lastCharacter)
{
return Error("Unexpected comma");
}
- if( !UpToParent() )
+ if(!UpToParent())
{
return false;
}
mState = STATE_VALUE;
}
- else if ( '"' == currentChar )
+ else if('"' == currentChar)
{
mState = STATE_KEY;
}
bool JsonParserState::HandleKeyState(char*& name)
{
name = EncodeString();
- if( nullptr == name )
+ if(nullptr == name)
{
return false;
}
- if( !ParseWhiteSpace() )
+ if(!ParseWhiteSpace())
{
return false;
}
- if( ':' != Char())
+ if(':' != Char())
{
return Error("Expected ':'");
}
- if( !ParseWhiteSpace() )
+ if(!ParseWhiteSpace())
{
return false;
}
{
Advance(1);
NewNode(name, TreeNode::STRING);
- if( char* value = EncodeString() )
+ if(char* value = EncodeString())
{
mCurrent.SetString(value);
}
{
return false;
}
- if( !UpToParent() )
+ if(!UpToParent())
{
return false;
}
bool JsonParserState::HandleCharacterNumberOrHyphen(const char* name)
{
NewNode(name, TreeNode::IS_NULL);
- if( !ParseNumber() )
+ if(!ParseNumber())
{
return false;
}
- if( !UpToParent() )
+ if(!UpToParent())
{
return false;
}
{
bool handled = true;
- if( '"' == currentChar )
+ if('"' == currentChar)
{
handled = HandleCharacterQuote(name);
}
- else if( IsNumber(currentChar) || currentChar == '-' )
+ else if(IsNumber(currentChar) || currentChar == '-')
{
handled = HandleCharacterNumberOrHyphen(name);
}
- else if( '{' == currentChar )
+ else if('{' == currentChar)
{
handled = HandleCharacterBracesStart(name, lastCharacter);
}
- else if( '}' == currentChar )
+ else if('}' == currentChar)
{
handled = HandleCharacterBracesEnd(lastCharacter);
}
- else if( '[' == currentChar )
+ else if('[' == currentChar)
{
handled = HandleCharacterSquareBracketStart(name);
}
- else if( ']' == currentChar )
+ else if(']' == currentChar)
{
handled = HandleCharacterSquareBracketEnd(lastCharacter);
}
- else if( 't' == currentChar )
+ else if('t' == currentChar)
{
handled = HandleCharacterLowercaseT(name);
}
- else if( 'n' == currentChar )
+ else if('n' == currentChar)
{
handled = HandleCharacterLowercaseN(name);
}
- else if( 'f' == currentChar)
+ else if('f' == currentChar)
{
handled = HandleCharacterLowercaseF(name);
}
- else if( ',' == currentChar )
+ else if(',' == currentChar)
{
handled = HandleCharacterComma(name);
}
{
Reset();
- if( 0 == source.size() )
+ if(0 == source.size())
{
return Error("Empty source buffer to parse");
}
mIter = source.begin();
mEnd = source.end();
- char* name = nullptr;
- char currentChar = 0;
- char lastCharacter = 0;
+ char* name = nullptr;
+ char currentChar = 0;
+ char lastCharacter = 0;
- if( !ParseWhiteSpace() )
+ if(!ParseWhiteSpace())
{
return false;
}
while(mIter != mEnd)
{
lastCharacter = currentChar;
- currentChar = Char();
+ currentChar = Char();
- switch( mState )
+ switch(mState)
{
case STATE_START:
{
} // while(1)
//
- if( mState != STATE_END )
+ if(mState != STATE_END)
{
return Error("Unexpected termination character");
}
{
mCurrent = TreeNodeManipulator(mRoot);
- mErrorDescription = nullptr;
- 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 )
+ if('}' == lastCharacter)
{
return Error("Expected a comma");
}
}
else
{
- if( !UpToParent() )
+ if(!UpToParent())
{
return false;
}
}
else
{
- if( !UpToParent() )
+ if(!UpToParent())
{
return false;
}
bool JsonParserState::HandleCharacterLowercaseT(const char* name)
{
NewNode(name, TreeNode::BOOLEAN);
- if( !ParseTrue() )
+ if(!ParseTrue())
{
return false;
}
- if( !UpToParent() )
+ if(!UpToParent())
{
return false;
}
bool JsonParserState::HandleCharacterLowercaseN(const char* name)
{
NewNode(name, TreeNode::IS_NULL);
- if( !ParseNULL() )
+ if(!ParseNULL())
{
return false;
}
- if( !UpToParent() )
+ if(!UpToParent())
{
return false;
}
bool JsonParserState::HandleCharacterLowercaseF(const char* name)
{
NewNode(name, TreeNode::BOOLEAN);
- if( !ParseFalse() )
+ if(!ParseFalse())
{
return false;
}
- if( !UpToParent() )
+ if(!UpToParent())
{
return false;
}
bool JsonParserState::HandleCharacterComma(const char* name)
{
- if( 0 == mCurrent.Size() )
+ if(0 == mCurrent.Size())
{
return Error("Missing Value");
}