1/*
2 * Copyright (C) 2014 The Android Open Source Project
3 *
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
7 *
8 *      http://www.apache.org/licenses/LICENSE-2.0
9 *
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.
15 */
16
17//------------------------------------------------------------------------
18//
19//   Module Name: dm_tree_node_class.cc
20//
21//   General Description:Contains the implementations of the methods of
22//                       DMNode class.
23//------------------------------------------------------------------------
24
25#include "dmdefs.h"
26#include "dm_tree_node_class.H"
27#include "dm_tree_class.H"
28#include "SyncML_DM_Archive.H"
29
30// For the mime type optimization
31#define DEFAULT_MIME_TYPE "text/plain"
32#define DEFAULT_MIME_TYPE_INTERNAL ""
33
34class DMTree;
35
36// Constructor that sets class UID to the object while creating the object
37DMNode::DMNode(BOOLEAN bPlugin):
38  pcParentOfNode(NULL),
39  pcFirstChild(NULL),
40  pcNextSibling(NULL)
41{
42  bFormat = 0;
43  m_nFlags = bPlugin ? enum_NodePlugin : 0;
44
45  //Only root of the archive has it set. Others will be NULL.
46  this->pArchive=NULL;
47#ifndef DM_IGNORE_TSTAMP_AND_VERSION
48  wTStamp = 0;
49  wVerNo = 0;
50#endif
51}
52
53//Destructor of the DMNode class
54DMNode::~DMNode()
55{
56  //Only root of the archive has it set. Others will be NULL.
57  if (this->pArchive != NULL)
58  {
59      if ( this->pArchive->getRootNode() == this )
60      {
61         this->pArchive->setRootNode(NULL);
62      }
63  }
64
65
66
67}
68
69
70SYNCML_DM_RET_STATUS_T DMNode::GetName(CPCHAR pbUri, DMString& strName )
71{
72    strName = abNodeName;
73    return SYNCML_DM_SUCCESS;
74}
75
76SYNCML_DM_RET_STATUS_T DMNode::SetName(CPCHAR pbUri, CPCHAR pbNewName)
77{
78    SYNCML_DM_RET_STATUS_T sRetStatus = SYNCML_DM_SUCCESS;
79
80    this->abNodeName = pbNewName;
81    return sRetStatus;
82}
83
84SYNCML_DM_RET_STATUS_T DMNode::GetTitle(CPCHAR pbUri,  DMString& ppbTitle)
85{
86    ppbTitle = m_strTitle;
87    return SYNCML_DM_SUCCESS;
88}
89
90SYNCML_DM_RET_STATUS_T DMNode::SetTitle(CPCHAR pbUri, CPCHAR pbNewTitle)
91{
92    m_strTitle = pbNewTitle;
93    return SYNCML_DM_SUCCESS;
94}
95
96#ifndef DM_IGNORE_TSTAMP_AND_VERSION
97
98SYNCML_DM_RET_STATUS_T DMNode::SetTStamp(CPCHAR pbUri, XPL_CLK_CLOCK_T timeStamp)
99{
100    wTStamp = timeStamp;
101    return SYNCML_DM_SUCCESS;
102}
103
104SYNCML_DM_RET_STATUS_T DMNode::SetVerNo(CPCHAR pbUri, UINT16 verNo)
105{
106    if (verNo == 0xffff)
107    {
108        wVerNo = 0;
109    }
110    else
111        wVerNo = verNo;
112    return SYNCML_DM_SUCCESS;
113}
114#endif
115
116DMNode* DMNode::GetChildByName( CPCHAR szName ) const
117{
118  DMNode *pNode = pcFirstChild;
119
120  while ( pNode && pNode->abNodeName != szName )
121    pNode = pNode->pcNextSibling;
122
123  return pNode;
124}
125
126DMNode* DMNode::GetNextSerializeItem()
127{
128  DMNode *pItem = this;
129
130  while ( pItem ) {
131    if ( !pItem->isPlugin() && !pItem->pArchive )
132      return pItem;
133
134    pItem = pItem->pcNextSibling;
135  }
136  return NULL;
137}
138
139void DMNode::ConvertPathToSkeleton( DMNode* psStartNode )
140{
141  DMNode *pNode = pcParentOfNode;
142
143  while ( pNode && pNode != psStartNode ){
144    pNode->m_nFlags |= enum_NodeSkeleton;
145    pNode = pNode->pcParentOfNode;
146  }
147
148  if ( pNode )
149    pNode->m_nFlags |= enum_NodeSkeleton;
150}
151
152CPCHAR DMNode::getType() const
153{
154    if (psType_ == DEFAULT_MIME_TYPE_INTERNAL) {
155        return DEFAULT_MIME_TYPE;
156    } else {
157        return psType_.c_str();
158    }
159}
160
161SYNCML_DM_RET_STATUS_T DMNode::setType(CPCHAR strType)
162{
163    if ( strType )
164    {
165        if ( DmStrcmp(strType,DEFAULT_MIME_TYPE) == 0 )
166        {
167            psType_ = DEFAULT_MIME_TYPE_INTERNAL;
168        } else {
169            psType_ = strType;
170            if ( psType_ == NULL && strType[0] )
171               return SYNCML_DM_DEVICE_FULL;
172        }
173    }
174    return SYNCML_DM_SUCCESS;
175}
176
177SYNCML_DM_RET_STATUS_T DMNode::set(const DMGetData * pData)
178{
179   SYNCML_DM_RET_STATUS_T res;
180
181   bFormat= pData->m_nFormat == SYNCML_DM_FORMAT_NODE_PDATA ? SYNCML_DM_FORMAT_NODE : pData->m_nFormat;
182
183   CPCHAR pMimeType = ( pData->m_oMimeType.getSize() ?  pData->getType() : NULL );
184
185   res = setType(pMimeType);
186   if ( res != SYNCML_DM_SUCCESS )
187      return res;
188
189   if ( pData->m_oData.getSize() && getData())
190   {
191      *getData() = pData->m_oData;
192      if ( getData()->getBuffer() == 0 )
193        return SYNCML_DM_DEVICE_FULL;
194   }
195   else
196	  if  ( getData() )
197	   {
198	      // Set boolean string value if it is omitted, otherwise size 0
199	      // will be returned for DM API call.
200	      if (!pData->m_oData.getSize() )
201		{
202		     if (bFormat == SYNCML_DM_FORMAT_BOOL)
203	      	    {
204	         	    (*getData()).assign("false");
205	      	    }
206	      	    else
207		   {
208			   (*getData()).clear();
209		   }
210	      }
211	   }
212
213   return SYNCML_DM_SUCCESS;
214}
215
216
217SYNCML_DM_RET_STATUS_T DMNode::set(CPCHAR strName, CPCHAR strTitle, const DMGetData * pData)
218{
219
220   if ( strName )
221   {
222      abNodeName = strName;
223      if ( abNodeName == NULL && strName[0] )
224        return SYNCML_DM_DEVICE_FULL;
225   }
226   else
227      return SYNCML_DM_FAIL;
228
229
230   if ( strTitle )
231   {
232      m_strTitle = strTitle;
233      if ( m_strTitle == NULL && strTitle[0] )
234        return SYNCML_DM_DEVICE_FULL;
235   }
236
237   return set(pData);
238
239}
240
241
242SYNCML_DM_RET_STATUS_T DMNode::set(const DMAddNodeProp * pNodeProp)
243{
244
245   m_nFlags = pNodeProp->m_nFlags;
246#ifndef DM_IGNORE_TSTAMP_AND_VERSION
247   wTStamp = pNodeProp->m_nTStamp;
248   wVerNo = pNodeProp->m_nVerNo;
249#endif
250
251   CPCHAR pTitle = ( pNodeProp->m_oTitle.getSize() ?  pNodeProp->getTitle() : NULL );
252   CPCHAR pName = ( pNodeProp->m_oName.getSize() ?  pNodeProp->getName() : NULL );
253
254   if ( getOverlayPIData() )
255   {
256      getOverlayPIData()->set_size( pNodeProp->m_oOPiData.getSize() );
257      if ( getOverlayPIData()->size() != pNodeProp->m_oOPiData.getSize() )
258        return SYNCML_DM_DEVICE_FULL;
259      memcpy( getOverlayPIData()->get_data(), pNodeProp->m_oOPiData.getBuffer(),
260        getOverlayPIData()->size() );
261   }
262
263   return set(pName,pTitle,(DMGetData*)pNodeProp);
264
265}
266
267#ifdef LOB_SUPPORT
268SYNCML_DM_RET_STATUS_T	DMNode::IsESN(CPCHAR pbUri, BOOLEAN& bESN)
269{
270    bESN = (m_nFlags & enum_NodeESN) != 0;
271   return SYNCML_DM_SUCCESS;
272}
273#endif
274