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