2 * Copyright (c) 2014 Samsung Electronics Co., Ltd.
4 * Licensed under the Apache License, Version 2.0 (the "License");
5 * you may not use this file except in compliance with the License.
6 * You may obtain a copy of the License at
8 * http://www.apache.org/licenses/LICENSE-2.0
10 * Unless required by applicable law or agreed to in writing, software
11 * distributed under the License is distributed on an "AS IS" BASIS,
12 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13 * See the License for the specific language governing permissions and
14 * limitations under the License.
23 #include <dali-toolkit/internal/builder/tree-node-manipulator.h>
25 #include <dali-toolkit/public-api/builder/tree-node.h>
39 void Indent(std::ostream& o, int indent)
41 for (int i = 0; i < indent; ++i)
49 TreeNodeManipulator::TreeNodeManipulator(TreeNode* node)
54 TreeNode* TreeNodeManipulator::NewTreeNode()
56 return new TreeNode();
59 void TreeNodeManipulator::ShallowCopy(const TreeNode* from, TreeNode* to)
61 DALI_ASSERT_DEBUG(from);
62 DALI_ASSERT_DEBUG(to);
66 to->mName = from->mName;
67 to->mType = from->mType;
68 to->mSubstituion = from->mSubstituion;
71 case TreeNode::INTEGER:
73 to->mIntValue = from->mIntValue;
78 to->mFloatValue = from->mFloatValue;
81 case TreeNode::STRING:
83 to->mStringValue = from->mStringValue;
86 case TreeNode::BOOLEAN:
88 to->mIntValue = from->mIntValue;
91 case TreeNode::IS_NULL:
92 case TreeNode::OBJECT:
102 void TreeNodeManipulator::MoveNodeStrings(VectorCharIter& start, const VectorCharIter& sentinel)
104 DALI_ASSERT_DEBUG(mNode && "Operation on NULL JSON node");
107 mNode->mName = CopyString(mNode->mName, start, sentinel);
110 if(TreeNode::STRING == mNode->mType)
112 mNode->mStringValue = CopyString(mNode->mStringValue, start, sentinel);
116 void TreeNodeManipulator::MoveStrings(VectorCharIter& start, const VectorCharIter& sentinel)
118 DALI_ASSERT_DEBUG(mNode && "Operation on NULL JSON node");
119 TreeNodeManipulator modify(mNode);
120 modify.MoveNodeStrings(start, sentinel);
121 RecurseMoveChildStrings(start, sentinel);
124 void TreeNodeManipulator::RecurseMoveChildStrings(VectorCharIter& start, const VectorCharIter& sentinel)
126 DALI_ASSERT_DEBUG(mNode && "Operation on NULL JSON node");
128 TreeNode* child = mNode->mFirstChild;
131 TreeNodeManipulator manipChild(child);
132 manipChild.MoveNodeStrings(start, sentinel);
133 child = child->mNextSibling;
136 child = mNode->mFirstChild;
139 TreeNodeManipulator manipChild(child);
140 manipChild.RecurseMoveChildStrings(start, sentinel);
141 child = child->mNextSibling;
145 void TreeNodeManipulator::RemoveChildren()
147 DALI_ASSERT_DEBUG(mNode && "Operation on NULL JSON node");
149 CollectNodes collector;
151 DepthFirst( mNode, collector );
153 for(CollectNodes::iterator iter = collector.nodes.begin(); iter != collector.nodes.end(); ++iter)
161 mNode->mFirstChild = NULL;
162 mNode->mLastChild = NULL;
165 TreeNode* TreeNodeManipulator::Copy(const TreeNode& tree, int& numberNodes, int& numberChars)
167 TreeNode* root = NewTreeNode();
169 ShallowCopy(&tree, root);
173 numberChars += std::strlen(tree.mName) + 1;
176 if(TreeNode::STRING == tree.mType)
178 numberChars += std::strlen(tree.mStringValue) + 1;
183 CopyChildren(&tree, root, numberNodes, numberChars);
188 void TreeNodeManipulator::CopyChildren(const TreeNode* from, TreeNode* to, int& numberNodes, int& numberChars)
190 DALI_ASSERT_DEBUG(from && "Operation on NULL JSON node");
191 DALI_ASSERT_DEBUG(to);
193 for( TreeNode::ConstIterator iter = from->CBegin(); iter != from->CEnd(); ++iter)
195 const TreeNode* child = &((*iter).second);
198 numberChars += std::strlen(child->mName) + 1;
201 if(TreeNode::STRING == child->mType)
203 numberChars += std::strlen(child->mStringValue) + 1;
206 TreeNode* newNode = NewTreeNode();
208 ShallowCopy(child, newNode);
210 TreeNodeManipulator modify(to);
212 modify.AddChild(newNode);
216 CopyChildren(child, newNode, numberNodes, numberChars);
220 TreeNode *TreeNodeManipulator::AddChild(TreeNode *rhs)
222 DALI_ASSERT_DEBUG(mNode && "Operation on NULL JSON node");
224 rhs->mParent = mNode;
225 if (mNode->mLastChild)
227 mNode->mLastChild = mNode->mLastChild->mNextSibling = rhs;
231 mNode->mFirstChild = mNode->mLastChild = rhs;
236 TreeNode::NodeType TreeNodeManipulator::GetType() const
238 DALI_ASSERT_DEBUG(mNode && "Operation on NULL JSON node");
240 return mNode->GetType();
243 size_t TreeNodeManipulator::Size() const
245 DALI_ASSERT_DEBUG(mNode && "Operation on NULL JSON node");
247 return mNode->Size();
250 void TreeNodeManipulator::SetType( TreeNode::NodeType type)
252 DALI_ASSERT_DEBUG(mNode && "Operation on NULL JSON node");
254 if( mNode->mType != type )
258 if( NULL != mNode->mFirstChild )
260 // value types have no children
261 bool removeChildren = ! (TreeNode::OBJECT == type || TreeNode::ARRAY == type);
263 // ie if swapping array for object
264 removeChildren = (removeChildren == true) ? true : type != mNode->mType;
266 // so remove any children
267 if( removeChildren && NULL != mNode->mFirstChild)
275 void TreeNodeManipulator::SetName( const char* name )
277 DALI_ASSERT_DEBUG(mNode && "Operation on NULL JSON node");
281 void TreeNodeManipulator::SetSubstitution( bool b )
283 DALI_ASSERT_DEBUG(mNode && "Operation on NULL JSON node");
284 mNode->mSubstituion = b;
287 TreeNode* TreeNodeManipulator::GetParent() const
289 DALI_ASSERT_DEBUG(mNode && "Operation on NULL JSON node");
290 return NULL == mNode ? NULL : mNode->mParent;
293 const TreeNode* TreeNodeManipulator::GetChild(const std::string& name) const
295 DALI_ASSERT_DEBUG(mNode && "Operation on NULL JSON node");
296 return NULL == mNode ? NULL : mNode->GetChild(name);
299 void TreeNodeManipulator::SetString( const char* string )
301 DALI_ASSERT_DEBUG(mNode && "Operation on NULL JSON node");
302 SetType(TreeNode::STRING);
303 mNode->mStringValue = string;
306 void TreeNodeManipulator::SetInteger( int i )
308 DALI_ASSERT_DEBUG(mNode && "Operation on NULL JSON node");
309 SetType(TreeNode::INTEGER);
310 mNode->mIntValue = i;
313 void TreeNodeManipulator::SetFloat( float f )
315 DALI_ASSERT_DEBUG(mNode && "Operation on NULL JSON node");
316 SetType(TreeNode::FLOAT);
317 mNode->mFloatValue = f;
320 void TreeNodeManipulator::SetBoolean( bool b )
322 DALI_ASSERT_DEBUG(mNode && "Operation on NULL JSON node");
323 SetType(TreeNode::BOOLEAN);
324 mNode->mIntValue = b == true ? 1 : 0;
327 void TreeNodeManipulator::Write(std::ostream& output, int indent) const
329 DALI_ASSERT_DEBUG(mNode && "Operation on NULL JSON node");
330 DoWrite(mNode, output, indent);
333 void TreeNodeManipulator::DoWrite(const TreeNode *value, std::ostream& output, int indent) const
335 DALI_ASSERT_DEBUG(value && "Operation on NULL JSON node");
337 Indent(output, indent);
339 if (value->GetName())
341 output << "\"" << value->GetName() << "\":";
344 switch(value->GetType())
346 case TreeNode::IS_NULL:
349 if(NULL != value->mNextSibling)
359 case TreeNode::OBJECT:
360 case TreeNode::ARRAY:
362 if( value->GetType() == TreeNode::OBJECT)
379 for (TreeNode::ConstIterator it = value->CBegin(); it != value->CEnd(); ++it)
381 DoWrite( &((*it).second), output, indent + 1);
383 Indent(output, indent);
384 if( value->GetType() == TreeNode::OBJECT )
402 case TreeNode::STRING:
404 output << "\"" << value->GetString() << "\"";
405 if(NULL != value->mNextSibling)
416 case TreeNode::INTEGER:
418 output << value->GetInteger();
419 if(NULL != value->mNextSibling)
430 case TreeNode::FLOAT:
432 output.setf( std::ios::floatfield );
433 output << value->GetFloat();
434 output.unsetf( std::ios::floatfield );
435 if(NULL != value->mNextSibling)
445 case TreeNode::BOOLEAN:
447 if( value->GetInteger() )
455 if(NULL != value->mNextSibling)
470 const TreeNode* FindIt(const std::string& childName, const TreeNode* node)
472 DALI_ASSERT_DEBUG(node);
474 const TreeNode* found = NULL;
478 if( NULL != (found = node->GetChild(childName)) )
484 for(TreeNode::ConstIterator iter = node->CBegin(); iter != node->CEnd(); ++iter)
486 if( NULL != (found = FindIt(childName, &((*iter).second)) ) )
496 char *CopyString( const char *fromString, VectorCharIter& iter, const VectorCharIter& sentinel)
498 DALI_ASSERT_DEBUG(fromString);
499 DALI_ASSERT_DEBUG(iter != sentinel);
501 char *start= &(*iter);
502 const char *ptr = fromString;
508 DALI_ASSERT_DEBUG(iter != sentinel);
518 } // namespace internal
520 } // namespace Toolkit