X-Git-Url: http://review.tizen.org/git/?p=platform%2Fcore%2Fuifw%2Fdali-toolkit.git;a=blobdiff_plain;f=optional%2Fdali-toolkit%2Finternal%2Fbuilder%2Fjson-parser-state.cpp;h=46c7550821cd6095cdec41eedb90b9af3a9468f5;hp=d7d51a46d41e0546a67269424da9115304c454d6;hb=d72610dbc3930e073808fce04bd5c9a37ef9666d;hpb=a881757839b7abb008873a68c67e17b3ba39669b diff --git a/optional/dali-toolkit/internal/builder/json-parser-state.cpp b/optional/dali-toolkit/internal/builder/json-parser-state.cpp deleted file mode 100644 index d7d51a4..0000000 --- a/optional/dali-toolkit/internal/builder/json-parser-state.cpp +++ /dev/null @@ -1,981 +0,0 @@ -/* - * Copyright (c) 2014 Samsung Electronics Co., Ltd. - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - * - */ - -// CLASS HEADER -#include - -// EXTERNAL -#include - -namespace Dali -{ - -namespace Toolkit -{ - -namespace Internal -{ - -namespace -{ - -// true if character represent a digit -inline bool IsDigit(char c) -{ - return (c >= '0' && c <= '9'); -} - -// convert string to integer -bool StringToInteger(const char *first, const char *last, int& out) -{ - int sign = 1; - if (first != last) - { - if (*first == '-') - { - sign = -1; - ++first; - } - else if (*first == '+') - { - ++first; - } - } - - // json error for int starting with zero - if( 0 == (*first - '0') && (first+1 != last)) - { - return false; - } - - int result = 0; - for (; first != last && IsDigit(*first); ++first) - { - result = 10 * result + (*first - '0'); - } - out = result * sign; - - if(first != last) - { - return false; - } - else - { - return true; - } -} - -// convert hexadecimal string to unsigned integer -bool HexStringToUnsignedInteger(const char *first, const char *last, unsigned int& out) -{ - unsigned int result = 0; - for (; first != last; ++first) - { - int digit; - if (IsDigit(*first)) - { - digit = *first - '0'; - } - else if (*first >= 'a' && *first <= 'f') - { - digit = *first - 'a' + 10; - } - else if (*first >= 'A' && *first <= 'F') - { - digit = *first - 'A' + 10; - } - else - { - break; - } - result = 16 * result + digit; - } - out = result; - - if(first != last) - { - return false; - } - else - { - return true; - } -} - -// convert string to floating point -bool StringToFloat(const char* first, const char* last, float& out) -{ - // sign - float sign = 1; - if (first != last) - { - if (*first == '-') - { - sign = -1; - ++first; - } - else if (*first == '+') - { - ++first; - } - } - - // integer part - float result = 0; - for (; first != last && IsDigit(*first); ++first) - { - result = 10 * result + (*first - '0'); - } - - // fraction part - if (first != last && *first == '.') - { - ++first; - - float inv_base = 0.1f; - for (; first != last && IsDigit(*first); ++first) - { - result += (*first - '0') * inv_base; - inv_base *= 0.1f; - } - } - - // result w\o exponent - result *= sign; - - // exponent - bool exponent_negative = false; - int exponent = 0; - if (first != last && (*first == 'e' || *first == 'E')) - { - ++first; - - if (*first == '-') - { - exponent_negative = true; - ++first; - } - else if (*first == '+') - { - ++first; - } - - if(first == last || !IsDigit(*first)) - { - return false; - } - - for (; first != last && IsDigit(*first); ++first) - { - exponent = 10 * exponent + (*first - '0'); - } - } - - if (exponent) - { - float power_of_ten = 10; - for (; exponent > 1; exponent--) - { - power_of_ten *= 10; - } - - if (exponent_negative) - { - result /= power_of_ten; - } - else - { - result *= power_of_ten; - } - } - - out = result; - - if(first != last) - { - return false; - } - else - { - return true; - } -} - - -bool IsNumber(char c) -{ - bool ret = false; - switch( c ) - { - case '0': - case '1': - case '2': - case '3': - case '4': - case '5': - case '6': - case '7': - case '8': - case '9': - { - ret = true; - break; - } - default: - { - ret = false; - } - } - return ret; -} - -} // anon 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) -{ - if(_root == NULL) - { - mFirstParse = true; - } -} - -TreeNode* JsonParserState::CreateNewNode(const char* name, TreeNode::NodeType type) -{ - TreeNode* node = NULL; - - node = TreeNodeManipulator::NewTreeNode(); - TreeNodeManipulator modifyNew(node); - modifyNew.SetType(type); - modifyNew.SetName(name); - if(mRoot == NULL) - { - mRoot = node; - mCurrent = TreeNodeManipulator(mRoot); - } - else - { - mCurrent.AddChild(node); - mCurrent = modifyNew; - } - - ++mNumberOfCreatedNodes; - - return node; - -} - -TreeNode* JsonParserState::NewNode(const char* name, TreeNode::NodeType type) -{ - TreeNode* node = NULL; - - if(mFirstParse) - { - node = CreateNewNode(name, type); - } - else - { - // a merging parse - - if(name) - { - const TreeNode* found = mCurrent.GetChild(name); - if( NULL != found ) - { - node = const_cast(found); - } - } - else - { - // if root node - if( mCurrent.GetParent() == NULL ) - { - node = mRoot; - } - } - - if(node) - { - // walk tree and deallocate children as were replacing this node - TreeNodeManipulator modify(node); - - modify.SetName(name); - // Set the type of the existing node, this may remove children where necessary - // (changing from container type to value type) - modify.SetType(type); - - mCurrent = modify; - } - else - { - // if not found then create new - node = CreateNewNode(name, type); - } - } - - return node; -} - -TreeNode* JsonParserState::GetRoot() -{ - return mRoot; -} - -bool JsonParserState::Error(const char* description) -{ - mErrorDescription = description; - return false; -} - -bool JsonParserState::ParseWhiteSpace() -{ - bool c_comment = false; - bool cpp_comment = false; - - // skip white space - char nextChar = 0; - while(1) - { - char c = Char(); - - if(c == '\xA') - { - NewLine(); - } - - if( AtLeast(2) ) - { - nextChar = mIter[1]; - } - else - { - nextChar = 0; - } - - if( cpp_comment ) - { - 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 == '/') ) - { - cpp_comment = true; - } - - if( c_comment ) - { - if( c == '*' && nextChar == '/' ) - { - c_comment = false; - Advance(2); - continue; - } - } - else if( !cpp_comment && (c == '/' && nextChar == '*') ) - { - c_comment = true; - } - - if( ! (c_comment || cpp_comment) ) - { - if( ! (c == '\x20' || c == '\x9' || c == '\xD' || c == '\xA' ) ) - { - break; - } - } - - if( AdvanceEnded(1) ) - { - break; - } - - } // while(1) - - return true; -} // ParseWhiteSpace - -bool JsonParserState::ParseSymbol(const std::string& symbol) -{ - if( AtLeast( symbol.size() ) ) - { - for(int i = 0; i < static_cast( symbol.size() ); ++i) - { - if(*mIter != symbol[i]) - { - return false; - } - Advance(1); - } - return true; - } - else - { - return false; - } -} - -bool JsonParserState::ParseTrue() -{ - if( ParseSymbol("true") ) - { - mCurrent.SetInteger(1); - mCurrent.SetType(TreeNode::BOOLEAN); - return true; - } - else - { - return Error("Unexpected character; expected symbol ie 'true'"); - } -} - -bool JsonParserState::ParseFalse() -{ - if( ParseSymbol("false") ) - { - mCurrent.SetInteger(0); - mCurrent.SetType(TreeNode::BOOLEAN); - return true; - } - else - { - return Error("Unexpected character; expected symbol ie 'false'"); - } -} - -bool JsonParserState::ParseNULL() -{ - if( ParseSymbol("null") ) - { - mCurrent.SetType(TreeNode::IS_NULL); - return true; - } - else - { - return Error("Unexpected character; expected symbol ie 'null'"); - } -} - -bool JsonParserState::ParseNumber() -{ - mCurrent.SetType( TreeNode::INTEGER ); - - VectorCharIter first = mIter; - char c = Char(); - - if( !(c == '-' || IsNumber(c) ) ) - { - return Error("Number must start with '-' or 0-9"); - } - - while ( IsNumber(c) || c == '.' || c == 'e' || c == 'E' || c == '+' || c == '-' ) - { - if (c == '.' || c == 'e' || c == 'E') - { - mCurrent.SetType( TreeNode::FLOAT ); - } - Advance(1); - c = Char(); - } - - if( mCurrent.GetType() == TreeNode::INTEGER ) - { - int i = 0; - if( StringToInteger(&(*first), &(*mIter), i ) ) - { - mCurrent.SetInteger(i); - } - else - { - return Error("Bad integer number"); - } - } - - if(mCurrent.GetType() == TreeNode::FLOAT) - { - float f = 0.f; - if( StringToFloat(&(*first), &(*mIter), f) ) - { - mCurrent.SetFloat(f); - } - else - { - return Error("Bad float number"); - } - } - - return (mCurrent.GetType() == TreeNode::INTEGER) || (mCurrent.GetType() == TreeNode::FLOAT); -} - -char* JsonParserState::EncodeString() -{ - int substitution = 0; - VectorCharIter first = mIter; - VectorCharIter last = mIter; - - while (*mIter) - { - if (static_cast(*mIter) < '\x20') - { - static_cast( Error("Control characters not allowed in strings") ); - return NULL; - } - else if (*mIter == '\\' && AtLeast(2)) - { - switch (*(mIter+1)) - { - case '"': - { - *last = '"'; - break; - } - case '\\': - { - *last = '\\'; - break; - } - case '/': - { - *last = '/'; - break; - } - case 'b': - { - *last = '\b'; - break; - } - case 'f': - { - *last = '\f'; - break; - } - case 'n': - { - *last = '\n'; - break; - } - case 'r': - { - *last = '\r'; - break; - } - case 't': - { - *last = '\t'; - break; - } - case 'u': - { - unsigned int codepoint; - if( !AtLeast(6) ) - { - static_cast( Error("Bad unicode codepoint; not enough characters") ); - return NULL; - } - if ( !HexStringToUnsignedInteger(&(*(mIter + 2)), &(*(mIter + 6)), codepoint) ) - { - static_cast( Error("Bad unicode codepoint") ); - return NULL; - } - - if (codepoint <= 0x7F) - { - *last = (char)codepoint; - } - else if (codepoint <= 0x7FF) - { - *last++ = (char)(0xC0 | (codepoint >> 6)); - *last = (char)(0x80 | (codepoint & 0x3F)); - } - else if (codepoint <= 0xFFFF) - { - *last++ = (char)(0xE0 | (codepoint >> 12)); - *last++ = (char)(0x80 | ((codepoint >> 6) & 0x3F)); - *last = (char)(0x80 | (codepoint & 0x3F)); - } - - Advance(4); - break; - } // case 'u' unicode - - default: - { - static_cast( Error("Unrecognized escape sequence") ); - return NULL; - } - } - - ++last; - Advance(2); - } - else if (*mIter == '{') - { - if((0 == substitution) && (*last != '\\')) - { - substitution = 1; - } - *last++ = *mIter; - Advance(1); - } - else if (*mIter == '}') - { - if(substitution) - { - substitution++; - } - *last++ = *mIter; - Advance(1); - } - else if (*mIter == '"') - { - *last = 0; - Advance(1); - break; - } - else - { - *last++ = *mIter; - Advance(1); - } - - } // while(*mIter) - - mNumberOfParsedChars += last - first; - mNumberOfParsedChars += 1 ; // null terminator - - mCurrent.SetSubstitution( substitution > 1 ); - - // return true; - return &(*first); - -} // ParseString() - -bool JsonParserState::ParseJson(VectorChar& source) -{ - Reset(); - - if( 0 == source.size() ) - { - return Error("Empty source buffer to parse"); - } - - mIter = source.begin(); - mEnd = source.end(); - - char* name = NULL; - char currentChar = 0; - char lastCharacter = 0; - - if( !ParseWhiteSpace() ) - { - return false; - } - - while(mIter != mEnd) - { - lastCharacter = currentChar; - currentChar = Char(); - - switch( mState ) - { - case STATE_START: - { - 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); - break; - } - case STATE_OBJECT: - { - 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); - break; - } - case STATE_KEY: - { - name = EncodeString(); - if( NULL == name ) - { - return false; - } - if( !ParseWhiteSpace() ) - { - return false; - } - if( ':' != Char()) - { - return Error("Expected ':'"); - } - if( !ParseWhiteSpace() ) - { - 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 == '-' ) - { - 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"); - } - - name = NULL; - - break; - } // case STATE_VALUE - case STATE_END: - { - return Error("Unexpected character. Json must have one object or array at its root"); - break; - } - } // switch(mState) - - } // while(1) - - // - if( mState != STATE_END ) - { - return Error("Unexpected termination character"); - } - - mIter = source.end(); - - return true; - -} // ParseJson - - -void JsonParserState::Reset() -{ - mCurrent = TreeNodeManipulator(mRoot); - - mErrorDescription = NULL; - mErrorNewLine = 0; - mErrorColumn = 0; - mErrorPosition = 0; -} - - -} // namespace Internal - -} // namespace Toolkit - -} // namespace Dali