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_util.c
20    General Description: Implementation of UTILITY functions provided by
21                         DMTNM module
22=======================================================================*/
23
24#include "dm_tree_util.h"
25#include "dm_uri_utils.h"
26#include "xpl_Logger.h"
27
28SYNCML_DM_RET_STATUS_T dmGetNodeValue(CPCHAR uriPath, DmtData& oDmtData)
29{
30   SYNCML_DM_RET_STATUS_T status = SYNCML_DM_SUCCESS;
31
32   DMGetData getData;
33   status = dmTreeObj.Get(uriPath, getData, SYNCML_DM_REQUEST_TYPE_INTERNAL);
34   if (status == SYNCML_DM_SUCCESS) {
35      dmBuildData(getData.m_nFormat, getData.m_oData, oDmtData);
36   }
37   return status;
38}
39
40SYNCML_DM_RET_STATUS_T dmBuildData(SYNCML_DM_FORMAT_T format, const DMBuffer & oData, DmtData & oDmtData)
41{
42
43   SYNCML_DM_RET_STATUS_T res = SYNCML_DM_SUCCESS;
44   switch (format)
45   {
46      case SYNCML_DM_FORMAT_CHR:
47      case SYNCML_DM_FORMAT_INT:
48      case SYNCML_DM_FORMAT_BOOL:
49      case SYNCML_DM_FORMAT_FLOAT:
50      case SYNCML_DM_FORMAT_DATE:
51      case SYNCML_DM_FORMAT_TIME:
52         res = oDmtData.SetString((CPCHAR)oData.getBuffer(), format);
53         break;
54
55      case SYNCML_DM_FORMAT_BIN:
56         res = oDmtData.SetBinary(oData.getBuffer(), oData.getSize());
57         break;
58
59      case SYNCML_DM_FORMAT_NULL:
60        oDmtData = DmtData( (CPCHAR) NULL );
61        break;
62
63      case SYNCML_DM_FORMAT_NODE:
64      case SYNCML_DM_FORMAT_INVALID:
65         oDmtData = DmtData();
66         break;
67
68      default:
69         oDmtData = DmtData();
70         return SYNCML_DM_UNSUPPORTED_MEDIATYPE_FORMAT;
71  }
72  return res;
73}
74
75
76SYNCML_DM_RET_STATUS_T DMGetData::set(SYNCML_DM_FORMAT_T wFormat,
77                                        CPCHAR pData,
78                                        UINT32 dataLength,
79                                        CPCHAR pMimeType)
80{
81
82    clear();
83    m_nFormat = wFormat;
84
85    if( dataLength != 0 && pData != NULL )
86    {
87      m_oData.assign(pData, dataLength);
88      if ( m_oData.getBuffer() == NULL )
89        return SYNCML_DM_DEVICE_FULL;
90    }
91
92    if( pMimeType )
93    {
94       m_oMimeType.assign(pMimeType);
95       if ( m_oMimeType.getBuffer() == NULL && pMimeType[0] )
96       return SYNCML_DM_DEVICE_FULL;
97    }
98
99    return (SYNCML_DM_SUCCESS);
100
101}
102
103#ifdef LOB_SUPPORT
104 SYNCML_DM_RET_STATUS_T DMGetData::set(DmtDataChunk  *dmtChunk, UINT32 dmtChunkoffset)
105{
106   m_chunkOffset = dmtChunkoffset;
107   chunkData = dmtChunk;
108    return (SYNCML_DM_SUCCESS);
109}
110void DMGetData::clearESNData()
111{	m_chunkOffset = 0L;
112	chunkData = NULL;
113	m_bESN = FALSE;
114}
115#endif
116
117SYNCML_DM_RET_STATUS_T DMGetData::set(const DmtData & data, CPCHAR pMimeType)
118{
119   SYNCML_DM_RET_STATUS_T res = SYNCML_DM_SUCCESS;
120
121   clear();
122#ifdef LOB_SUPPORT
123  clearESNData();
124#endif
125   switch ( data.GetType() )
126   {
127     default:
128       {
129           DMString strValue;
130           data.GetString(strValue);
131           if ( strValue.length() )
132           {
133             m_oData.assign(strValue);
134             if ( m_oData.getBuffer() == NULL )
135                 return SYNCML_DM_DEVICE_FULL;
136           }
137       }
138       break;
139
140     case SYNCML_DM_DATAFORMAT_STRING:
141       {
142           const DMString & strValue = data.GetStringValue();
143           if ( strValue.length() )
144           {
145             m_oData.assign(strValue);
146             if ( m_oData.getBuffer() == NULL )
147                 return SYNCML_DM_DEVICE_FULL;
148           }
149       }
150       break;
151
152     case SYNCML_DM_DATAFORMAT_UNDEFINED:
153     case SYNCML_DM_DATAFORMAT_NULL:
154       break;
155
156     case SYNCML_DM_DATAFORMAT_BIN:
157       {
158           DMVector<UINT8> & buffer = (DMVector<UINT8> &)data.GetBinaryValue();
159           if ( buffer.size() )
160           {
161              m_oData.assign(buffer.get_data(), buffer.size());
162              if ( m_oData.getBuffer() == NULL )
163                 return SYNCML_DM_DEVICE_FULL;
164           }
165       }
166       break;
167   }
168
169
170   switch ( data.GetType() )
171   {
172    case SYNCML_DM_DATAFORMAT_UNDEFINED:
173      m_nFormat=SYNCML_DM_FORMAT_INVALID;
174      break;
175
176    case SYNCML_DM_DATAFORMAT_NULL:
177    case SYNCML_DM_DATAFORMAT_BIN:
178    case SYNCML_DM_DATAFORMAT_STRING:
179    case SYNCML_DM_DATAFORMAT_INT:
180    case SYNCML_DM_DATAFORMAT_FLOAT:
181    case SYNCML_DM_DATAFORMAT_DATE:
182    case SYNCML_DM_DATAFORMAT_TIME:
183    case SYNCML_DM_DATAFORMAT_BOOL:
184      m_nFormat=data.GetType();
185      break;
186   }
187
188   if( pMimeType )
189   {
190      m_oMimeType.assign(pMimeType);
191      if ( m_oMimeType.getBuffer() == NULL && pMimeType[0] )
192         return SYNCML_DM_DEVICE_FULL;
193   }
194
195   return (SYNCML_DM_SUCCESS);
196}
197
198SYNCML_DM_RET_STATUS_T DMAddData::set(SYNCML_DM_FORMAT_T wFormat,
199						  CPCHAR pMimeType)
200{
201    return  DMGetData::set(wFormat, NULL, 0, pMimeType);
202
203}
204
205SYNCML_DM_RET_STATUS_T DMAddData::set(CPCHAR pURI,
206                            SYNCML_DM_FORMAT_T wFormat,
207                            CPCHAR pData,
208                            UINT32 dataLength,
209                            CPCHAR pMimeType)
210{
211    SYNCML_DM_RET_STATUS_T res = SYNCML_DM_SUCCESS;
212
213    clear();
214#ifdef LOB_SUPPORT
215  clearESNData();
216#endif
217
218    res = DMGetData::set(wFormat,pData,dataLength, pMimeType);
219    if ( res != SYNCML_DM_SUCCESS )
220        return res;
221
222    if ( pURI )
223    {
224        m_oURI.assign(pURI);
225        if ( m_oURI.getBuffer() == NULL )
226             return SYNCML_DM_DEVICE_FULL;
227    }
228
229    return (SYNCML_DM_SUCCESS);
230}
231
232#ifdef LOB_SUPPORT
233 SYNCML_DM_RET_STATUS_T DMAddData::set(CPCHAR pURI,
234  							DmtDataChunk  *dmtChunk,
235  							UINT32 dmtChunkoffset,
236  							BOOLEAN isLastChunk)
237{
238   SYNCML_DM_RET_STATUS_T res = SYNCML_DM_SUCCESS;
239   m_oURI.clear();
240
241   if ( pURI )
242   {
243       m_oURI.assign(pURI);
244       if ( pURI[0] && m_oURI.getBuffer() == NULL )
245           return SYNCML_DM_DEVICE_FULL;
246   }
247
248   res = DMGetData::set(dmtChunk, dmtChunkoffset);
249   if ( res != SYNCML_DM_SUCCESS )
250      return res;
251
252   m_bLastChunk = isLastChunk;
253   return (SYNCML_DM_SUCCESS);
254}
255#endif
256SYNCML_DM_RET_STATUS_T DMAddData::set(CPCHAR pURI, const DmtData & data, CPCHAR pMimeType)
257{
258
259   SYNCML_DM_RET_STATUS_T res = SYNCML_DM_SUCCESS;
260
261   m_oURI.clear();
262
263   res = DMGetData::set(data, pMimeType);
264   if ( res != SYNCML_DM_SUCCESS )
265      return res;
266
267   if ( pURI )
268   {
269       m_oURI.assign(pURI);
270       if ( pURI[0] && m_oURI.getBuffer() == NULL )
271           return SYNCML_DM_DEVICE_FULL;
272   }
273
274   return (SYNCML_DM_SUCCESS);
275}
276
277#ifdef LOB_SUPPORT
278SYNCML_DM_RET_STATUS_T DMAddNodeProp::setESNFileName(CPCHAR pFileName)
279{
280    if ( pFileName )
281    {
282        m_oESNFileName.assign(pFileName);
283        if ( pFileName[0] && m_oESNFileName.getBuffer() == NULL )
284           return SYNCML_DM_DEVICE_FULL;
285    }
286   return (SYNCML_DM_SUCCESS);
287}
288#endif
289
290
291SYNCML_DM_RET_STATUS_T DMAddNodeProp::set(CPCHAR pName,
292                                           CPCHAR pTitle,
293                                           SYNCML_DM_FORMAT_T wFormat,
294                                           CPCHAR pData,
295                                           UINT32 dataLength,
296                                           CPCHAR pMimeType,
297                                           UINT16 flag)
298{
299
300    SYNCML_DM_RET_STATUS_T res = SYNCML_DM_SUCCESS;
301
302    m_oName.clear();
303    m_oTitle.clear();
304
305    res = DMAddData::set(NULL, wFormat, pData, dataLength, pMimeType);
306    if ( res != SYNCML_DM_SUCCESS )
307       return res;
308
309    if ( pName )
310    {
311        m_oName.assign(pName);
312        if ( pName[0] && m_oName.getBuffer() == NULL )
313           return SYNCML_DM_DEVICE_FULL;
314    }
315
316    if ( pTitle )
317    {
318        m_oTitle.assign(pName);
319        if ( pTitle[0] && m_oTitle.getBuffer() == NULL )
320           return SYNCML_DM_DEVICE_FULL;
321    }
322
323    m_nFlags = flag;
324
325    return SYNCML_DM_SUCCESS;
326
327
328
329}
330
331
332
333 /**
334 * Free the memory of the GET data structure in the Map
335 *
336 * @author Andy
337 * @param getDataMap the GET data structure Map to be free
338 * @return the status of the operation
339 */
340void dmFreeGetMap( DMMap<DMString, UINT32>& getDataMap)
341{
342   DMGetData* tmpData = NULL;
343   for ( DMMap<DMString, UINT32>::POS it = getDataMap.begin(); it < getDataMap.end(); it++ )
344   {
345       tmpData = (DMGetData*)getDataMap.get_value(it);
346
347       if (tmpData != NULL)
348         delete tmpData;
349   }
350
351   getDataMap.clear();
352}
353
354/**
355 * Free the memory of the ADD data structure in the Map
356 *
357 * @author Andy
358 * @param addDataMap the ADD data structure Map to be free
359 * @return the status of the operation
360 */
361void dmFreeAddMap( DMMap<DMString, UINT32>& addDataMap)
362{
363   DMAddData * tmpData = NULL;
364   for ( DMMap<DMString, UINT32>::POS it = addDataMap.begin(); it < addDataMap.end(); it++ )
365   {
366       tmpData = (DMAddData *)addDataMap.get_value(it);
367       delete tmpData;
368   }
369   addDataMap.clear();
370}
371
372
373/**
374 * Convert the GET data map to ADD data map
375 *
376 * @author Andy
377 * @param path the path to the parent of the nodes in the map
378 * @param mapNodes, the GET data map
379 * @param newChildrenMap the ADD data map
380 * @return the status of the operation
381 */
382SYNCML_DM_RET_STATUS_T dmConvertDataMap(CPCHAR path, const DMMap<DMString, DmtData>& mapNodes, DMMap<DMString, UINT32>& newChildrenMap)
383{
384  SYNCML_DM_RET_STATUS_T res;
385  DMAddData * pData = NULL;
386
387  for ( DMMap<DMString, DmtData>::POS it = mapNodes.begin(); it != mapNodes.end(); it++ )
388  {
389    DMString strChildPath = path;
390    strChildPath += "/";
391    strChildPath += mapNodes.get_key( it );
392    pData = new DMAddData();
393    if ( pData == NULL )
394    {
395        XPL_LOG_DM_TMN_Error(("dmConvertDataMap : unable allocate memory\n"));
396        return SYNCML_DM_DEVICE_FULL;
397    }
398
399    res = pData->set(strChildPath,mapNodes.get_value( it ),"text/plain");
400    if ( res != SYNCML_DM_SUCCESS )
401    {
402      delete pData;
403      return res;
404    }
405    newChildrenMap.put(mapNodes.get_key( it ), (UINT32)pData);
406  }
407
408  return SYNCML_DM_SUCCESS;
409}
410