Merge "Support moving of native-image-interface and image-operations to public-ap...
[platform/core/uifw/dali-toolkit.git] / dali-toolkit / internal / builder / json-parser-state.h
1 #ifndef __DALI_JSON_PARSE_STATE_H__
2 #define __DALI_JSON_PARSE_STATE_H__
3
4 /*
5  * Copyright (c) 2014 Samsung Electronics Co., Ltd.
6  *
7  * Licensed under the Apache License, Version 2.0 (the "License");
8  * you may not use this file except in compliance with the License.
9  * You may obtain a copy of the License at
10  *
11  * http://www.apache.org/licenses/LICENSE-2.0
12  *
13  * Unless required by applicable law or agreed to in writing, software
14  * distributed under the License is distributed on an "AS IS" BASIS,
15  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
16  * See the License for the specific language governing permissions and
17  * limitations under the License.
18  *
19  */
20
21 // EXTERNAL INCLUDES
22 #include <dali/public-api/common/dali-common.h>
23
24 // INTERNAL INCLUDES
25 #include <dali-toolkit/devel-api/builder/tree-node.h>
26
27 #include <dali-toolkit/internal/builder/tree-node-manipulator.h>
28
29 namespace Dali
30 {
31
32 namespace Toolkit
33 {
34
35 namespace Internal
36 {
37
38 /*
39  * A safer std::advance()
40  */
41 template <typename IteratorType,typename EndIteratorType>
42 inline int AdvanceIter(IteratorType& iter, EndIteratorType& end, int n)
43 {
44   for(int i =0; i < n; ++i)
45   {
46     if(iter == end)
47     {
48       return n - i;
49     }
50     ++iter;
51   }
52   return n;
53 }
54
55 /*
56  * Maintains parser state machine
57  *
58  * If a NULL root node is passed in the constructor then a faster non merging parse is performed (the first pass).
59  * Otherwise the json tree is merged (and requires slower searching)
60  */
61 class JsonParserState
62 {
63 public:
64   /*
65    * Constructor
66    * @param tree Tree to start with, pass NULL if no existing tree
67    */
68   explicit JsonParserState(TreeNode* tree);
69
70   /*
71    * Parse json source
72    * The source is modified in place
73    * @param source The vector buffer to parse
74    * @return true if parsed successfully
75    */
76   bool ParseJson(VectorChar& source);
77
78   /*
79    * Get the root node
80    * @return The root TreeNode
81    */
82   TreeNode* GetRoot();
83
84   /*
85    * Get the error description of the last parse
86    * @return The error description or NULL if no error
87    */
88   const char* GetErrorDescription() { return mErrorDescription; }
89
90   /*
91    * Get the error line number
92    * @return The line number of the error
93    */
94   int GetErrorLineNumber() { return mErrorNewLine; }
95
96   /*
97    * Get the error column
98    * @return The error column
99    */
100   int GetErrorColumn() { return mErrorColumn; }
101
102   /*
103    * Get the error position
104    * @return The error position
105    */
106   int GetErrorPosition() { return mErrorPosition; }
107
108   /*
109    * Get the size of the string data that has been parsed
110    * @return The size of string data
111    */
112   int GetParsedStringSize() { return mNumberOfParsedChars; };
113
114   /*
115    * Get the number of nodes created
116    * @return The number of nodes
117    */
118   int GetCreatedNodeCount() { return mNumberOfCreatedNodes; };
119
120 private:
121   VectorCharIter mIter;                ///< Current position
122   VectorCharIter mStart;               ///< Start position
123   VectorCharIter mEnd;                 ///< End of buffer being parsed
124   TreeNode* mRoot;                     ///< Root node created
125   TreeNodeManipulator mCurrent;        ///< The Current modifiable node
126   const char* mErrorDescription;       ///< The error description if set
127   int mErrorNewLine;                   ///< The error line number
128   int mErrorColumn;                    ///< The error column
129   int mErrorPosition;                  ///< The error position
130   int mNumberOfParsedChars;            ///< The size of string data
131   int mNumberOfCreatedNodes;           ///< The number of nodes created
132   bool mFirstParse;                    ///< Flag if first parse
133
134   /*
135    * The current parse state
136    */
137   enum State
138   {
139     STATE_START,
140     STATE_OBJECT,
141     STATE_KEY,
142     STATE_VALUE,
143     STATE_END,
144   };
145
146   State mState;
147
148   // inhibited copy construct and assignment
149   JsonParserState(const JsonParserState&);
150   const JsonParserState& operator=(const JsonParserState&);
151
152   /*
153    * Parse over white space
154    * Increments the current position
155    * @return true if no parse errors
156    */
157   bool ParseWhiteSpace();
158
159   /*
160    * Parse over a number, setting the current node if found
161    * Increments the current position. Sets error data if parse error.
162    * @return true if found, false if parse error
163    */
164   bool ParseNumber();
165
166   /*
167    * Parse over a symbol
168    * Increments the current position. Sets error data if parse error.
169    * @return true if found, false if parse error
170    */
171   bool ParseSymbol(const std::string& symbol);
172
173   /*
174    * Parse over 'true' symbol, setting the current node if found
175    * Increments the current position. Sets error data if parse error.
176    * @return true if found, false if parse error
177    */
178   bool ParseTrue();
179
180   /*
181    * Parse over 'false' symbol, setting the current node if found
182    * Increments the current position. Sets error data if parse error.
183    * @return true if found, false if parse error
184    */
185   bool ParseFalse();
186
187   /*
188    * Parse over 'null' symbol, setting the current node if found
189    * Increments the current position. Sets error data if parse error.
190    * @return true if found, false if parse error
191    */
192   bool ParseNULL();
193
194   /*
195    * Parse over a string from the current position and insert escaped
196    * control characters in place in the string and a null terminator.
197    * This function works from and modifes the current buffer position.
198    * @return the start of the null terminated string
199    */
200   char* EncodeString();
201
202   /*
203    * Create a new node with name and type
204    */
205   TreeNode* CreateNewNode(const char* name, TreeNode::NodeType type);
206
207   /*
208    * Create a new node if first parse, else check if the node already
209    * exists and set it to a new type
210    */
211   TreeNode* NewNode(const char* name, TreeNode::NodeType type);
212
213   /*
214    * Set error meta data
215    * @returns always false.
216    */
217   bool Error(const char* description);
218
219   /*
220    * Reset state for another parse
221    */
222   void Reset();
223
224   /*
225    * Set current to its parent
226    * @return true if we had a parent, false and error otherwise
227    */
228   inline bool UpToParent()
229   {
230     if(NULL == mCurrent.GetParent())
231     {
232       return Error("Attempt to walk up above root");
233     }
234     mCurrent = TreeNodeManipulator( mCurrent.GetParent() );
235     return true;
236   }
237
238   /*
239    * Get the current character
240    */
241   inline char Char()
242   {
243     return *mIter;
244   }
245
246   /*
247    * @return True if there are at least n character left
248    */
249   inline bool AtLeast(int n)
250   {
251     // The standard suggests vector.end() can be decremented as
252     //   iter v.back() { *--v.end() }
253     // (ISO/IEC 14882:2003 C++ Standard 23.1.1/12 – Sequences)
254     return (mEnd - mIter) > n;
255   }
256
257   /*
258    * @return True if at the end of the data to parse
259    */
260   inline bool AtEnd()
261   {
262     return mEnd == mIter;
263   }
264
265   /*
266    * Advance current position by n characters or stop at mEnd
267    */
268   inline void Advance(int n)
269   {
270     int c = AdvanceIter(mIter, mEnd, n);
271     mErrorPosition += c;
272     mErrorColumn   += c;
273   }
274
275   /*
276    * Advance by n charaters and return true if we reached the end
277    */
278   inline bool AdvanceEnded(int n)
279   {
280     int c = AdvanceIter(mIter, mEnd, n);
281     mErrorPosition += c;
282     mErrorColumn   += c;
283     return mEnd == mIter;
284   }
285
286   /*
287    * Advance by at least n characters (stopping at mEnd) and skip any whitespace after n.
288    */
289   inline void AdvanceSkipWhiteSpace(int n)
290   {
291     int c = AdvanceIter(mIter, mEnd, n);
292     mErrorPosition += c;
293     mErrorColumn   += c;
294     static_cast<void>( ParseWhiteSpace() );
295   }
296
297   /*
298    * Increment new line counters
299    */
300   inline void NewLine()
301   {
302     ++mErrorNewLine;
303     mErrorColumn = 0;
304   }
305
306 };
307
308
309 } // namespace Internal
310
311 } // namespace Toolkit
312
313 } // namespace Dali
314
315
316 #endif // header