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#include "dmMemory.h"
18#include "dmdefs.h"
19#include "dmt.hpp"
20#include "SyncML_PlugIn_WBXMLLog.H"
21#include "dmtRWPlugin.hpp"
22#include "xpl_File.h"
23#include "dm_uri_utils.h"
24#include "dm_tree_class.H"
25
26#ifdef TEST_DM_RECOVERY
27#include <unistd.h>
28extern char power_fail_point[];
29#endif
30
31DmtRWPluginTree::DmtRWPluginTree()
32{
33    fpLog = NULL;
34    log = NULL;
35    m_Playback = FALSE;
36   m_strLogPath = NULL;
37   m_ESNDirty = FALSE;
38   m_bIsAtomic = FALSE;
39}
40
41DmtRWPluginTree::~DmtRWPluginTree()
42{
43    if(fpLog != NULL)
44        delete fpLog;
45
46    if(this->log != NULL)
47        delete this->log;
48}
49
50SYNCML_DM_RET_STATUS_T
51DmtRWPluginTree::setLogFileHandle(DMFileHandler* fileHandle)
52{
53    SYNCML_DM_RET_STATUS_T dm_stat = SYNCML_DM_SUCCESS;
54    if(this->log != NULL)
55    {
56        delete this->log;
57        this->log = NULL;
58    }
59    if(fpLog != NULL)
60      delete fpLog;
61
62    fpLog = fileHandle;
63    this->log = new SyncML_PlugIn_WBXMLLog(this,(CPCHAR) m_strRootPath.c_str());
64    if(this->log != NULL)
65        dm_stat = this->log->setLogFileHandle(fpLog);
66    else
67        dm_stat = SYNCML_DM_FAIL;
68
69    return dm_stat;
70}
71
72SYNCML_DM_RET_STATUS_T
73DmtRWPluginTree::InitLog ()
74{
75    SYNCML_DM_RET_STATUS_T dm_stat = SYNCML_DM_SUCCESS;
76    if(this->log  != NULL)
77        return SYNCML_DM_SUCCESS;
78
79    if(m_strLogPath == NULL)
80    {
81        DMString file_name;
82        char uniqueStr[20];
83        XPL_CLK_LONG_CLOCK_T curTime = XPL_CLK_GetClockMs();
84        DmSprintf(uniqueStr, "%lld", curTime);
85        if(uniqueStr[0] == '-')
86           uniqueStr[0]='L';
87
88     dmTreeObj.GetWritableFileSystemFullPath( m_strLogPath );
89
90        CPCHAR pT = m_strLogPath.c_str();
91        if (pT[m_strLogPath.length()-1] != '/')
92          m_strLogPath += "/";
93
94        XPL_FS_MkDir(m_strLogPath);
95        m_strLogPath += uniqueStr;
96        m_strLogPath +=  ".log";
97    }
98    this->log = new SyncML_PlugIn_WBXMLLog(this,(CPCHAR) m_strRootPath.c_str());
99    if(this->log == NULL)
100       return SYNCML_DM_FAIL;
101    dm_stat = this->log->InitLog(m_strLogPath.c_str());
102    if(dm_stat != SYNCML_DM_SUCCESS)
103            return dm_stat;
104
105    return SYNCML_DM_SUCCESS;
106}
107
108SYNCML_DM_RET_STATUS_T
109DmtRWPluginTree::LogCommand(SYNCML_DM_PLUGIN_COMMAND_T type,
110                                 CPCHAR pbURI,
111                                 SYNCML_DM_PLUGIN_COMMAND_ATTRIBUTE_T attribute,
112                                 const DmtNode * inNode)
113{
114    if(m_Playback == TRUE)
115       return SYNCML_DM_SUCCESS;
116
117    SYNCML_DM_RET_STATUS_T  dm_stat = InitLog();
118    if(this->log == NULL)
119       return dm_stat;
120
121    switch ( type )
122    {
123       case SYNCML_DM_PLUGIN_ADD:
124           dm_stat = log->logCommand(SYNCML_DM_PLUGIN_DELETE, pbURI, attribute, inNode);
125           break;
126
127       case SYNCML_DM_PLUGIN_REPLACE:
128           dm_stat = log->logCommand(SYNCML_DM_PLUGIN_REPLACE, pbURI, attribute, inNode);
129           break;
130
131       case SYNCML_DM_PLUGIN_DELETE:
132           if(DmStrlen(pbURI) != 0)
133              log->logCommand(SYNCML_DM_PLUGIN_ADD_CHILD, pbURI, attribute, inNode);
134           dm_stat = log->logCommand(SYNCML_DM_PLUGIN_ADD, pbURI, attribute, inNode);
135           break;
136    }
137    return dm_stat;
138}
139
140SYNCML_DM_RET_STATUS_T DmtRWPluginTree::Verify()
141{
142   //@@@TODO
143    return SYNCML_DM_SUCCESS;
144}
145SYNCML_DM_RET_STATUS_T DmtRWPluginTree::CreateInteriorNodeInternal( CPCHAR path, PDmtNode& ptrCreatedNode, const DMStringVector & childNodeNames)
146{
147    PDmtRWPluginNode pNode;
148    SYNCML_DM_RET_STATUS_T dm_stat;
149
150    pNode = new DmtRWPluginNode();
151    if ( pNode == NULL )
152        return SYNCML_DM_DEVICE_FULL;
153
154    dm_stat = pNode->Init(this, path, childNodeNames);
155    if ( dm_stat != SYNCML_DM_SUCCESS )
156        return dm_stat;
157
158    dm_stat = this->SetNode(path, PDmtNode(pNode));
159    if ( dm_stat == SYNCML_DM_SUCCESS )
160        dm_stat = GetNode( path, ptrCreatedNode );
161
162    return dm_stat;
163}
164
165SYNCML_DM_RET_STATUS_T DmtRWPluginTree::CreateLeafNodeInternal( CPCHAR path, PDmtNode& ptrCreatedNode, const DmtData& value )
166{
167    PDmtRWPluginNode pNode;
168    SYNCML_DM_RET_STATUS_T dm_stat;
169
170    pNode=new DmtRWPluginNode();
171    if ( pNode == NULL )
172        return SYNCML_DM_DEVICE_FULL;
173
174     dm_stat = pNode->Init(this, path, value);
175    if ( dm_stat != SYNCML_DM_SUCCESS )
176        return dm_stat;
177
178    dm_stat = this->SetNode(path, PDmtNode(pNode));
179    if ( dm_stat == SYNCML_DM_SUCCESS )
180        dm_stat = GetNode( path, ptrCreatedNode );
181
182    return dm_stat;
183}
184
185SYNCML_DM_RET_STATUS_T DmtRWPluginTree::DeleteSubTree( PDmtNode ptrNode)
186{
187    SYNCML_DM_RET_STATUS_T dm_stat = SYNCML_DM_SUCCESS;
188    DMString nodePath;
189    if(!ptrNode->IsLeaf())
190    {
191        DMVector<PDmtNode> oChildren;
192        dm_stat = ptrNode->GetChildNodes( oChildren );
193        if ( dm_stat != SYNCML_DM_SUCCESS )
194            return dm_stat;
195
196        for ( int i = 0; i < oChildren.size(); i++ )
197        {
198            if (oChildren[i]->IsLeaf() )
199            {
200                dm_stat = oChildren[i]->GetPath(nodePath);
201                if ( dm_stat == SYNCML_DM_SUCCESS )
202                {
203                    dm_stat = this->RemoveNode(nodePath);
204                    oChildren[i] = NULL;
205                }
206            }
207            else
208               dm_stat =DeleteSubTree(oChildren[i]);
209
210            if( dm_stat != SYNCML_DM_SUCCESS)
211                return dm_stat;
212        }
213  }
214
215  dm_stat = ptrNode->GetPath(nodePath);
216  if ( dm_stat == SYNCML_DM_SUCCESS )
217    dm_stat = this->RemoveNode(nodePath);
218  ptrNode = NULL;
219
220  return dm_stat;
221
222}
223
224SYNCML_DM_RET_STATUS_T DmtRWPluginTree::DeleteNode( CPCHAR path )
225{
226    SYNCML_DM_RET_STATUS_T dm_stat = SYNCML_DM_SUCCESS;
227    PDmtNode ptrNode;
228
229    dm_stat = GetNode( path, ptrNode);
230    if ( dm_stat != SYNCML_DM_SUCCESS)
231        return dm_stat;
232
233#ifdef LOB_SUPPORT
234    // Create temporary storage for ESN
235    dm_stat = BackupESNdata(path);
236    if ( dm_stat != SYNCML_DM_SUCCESS)
237        return dm_stat;
238
239#endif
240
241    dm_stat = LogCommand(SYNCML_DM_PLUGIN_DELETE, path, SYNCML_DM_PLUGIN_COMMAND_ON_NODE, ptrNode);
242    if ( dm_stat != SYNCML_DM_SUCCESS)
243        return dm_stat;
244
245    dm_stat = DeleteSubTree(ptrNode);
246    if ( dm_stat != SYNCML_DM_SUCCESS)
247        return dm_stat;
248
249    // Is it the root node ?
250    if(DmStrlen(path) == 0)
251        return dm_stat;
252
253    DMString strURI;
254    DMString strKey;
255    DmParseURI( path, strURI, strKey );
256
257
258    DMStringVector oChildren;
259    dm_stat = this->GetChildNodeNames(strURI.c_str(), oChildren);
260    if ( dm_stat != SYNCML_DM_SUCCESS)
261        return dm_stat;
262
263    // Is the plugin root node?
264    if(strURI.length() == 0)
265    {
266        for (INT32 i = 0; i < oChildren.size(); i++ )
267        {
268            if (!DmStrcmp(oChildren[i].c_str() , path))
269                oChildren.remove(i);
270        }
271    }
272    else
273    {
274        for ( INT32 i = 0; i < oChildren.size(); i++ )
275        {
276            if (!DmStrcmp(oChildren[i].c_str() , strKey.c_str()))
277                oChildren.remove(i);
278        }
279    }
280
281      // Remove link to parent node
282    dm_stat = GetNode( strURI.c_str(), ptrNode);
283    if ( dm_stat != SYNCML_DM_SUCCESS)
284        return dm_stat;
285
286
287    DmtData m_value;
288    dm_stat = m_value.SetNodeValue(oChildren);
289
290    if ( dm_stat != SYNCML_DM_SUCCESS)
291        return dm_stat;
292
293    // Turn off logging temporarilly
294    BOOLEAN needLogging= m_Playback;
295    m_Playback = TRUE;
296    dm_stat = ptrNode->SetValue(m_value);
297    m_Playback = needLogging;
298
299    return dm_stat;
300}
301//--------------------------------------------------------------------------------------------
302// FUNCTION        : DmtRWPluginNode::RemoveNode
303// DESCRIPTION     : Remove a node from memory
304// ARGUMENTS PASSED:
305//
306// RETURN VALUE    : SYNCML_DM_RET_STATUS_T : Returns SYNCML_DM_SUCCESS if success, otherwise fails
307//
308//--------------------------------------------------------------------------------------------
309SYNCML_DM_RET_STATUS_T DmtRWPluginTree::RemoveNode(CPCHAR path)
310{
311    SYNCML_DM_RET_STATUS_T dm_stat = SYNCML_DM_SUCCESS;
312    PDmtNode ptrNode;
313
314    dm_stat = GetNode( path, ptrNode);
315    if ( dm_stat != SYNCML_DM_SUCCESS)
316        return dm_stat;
317#ifdef LOB_SUPPORT
318   if(ptrNode->IsExternalStorageNode())
319  {
320      PDmtRWPluginNode pRWNode = (DmtRWPluginNode *) ((DmtNode *)ptrNode);
321      dm_stat = pRWNode->Delete();
322     if ( dm_stat != SYNCML_DM_SUCCESS)
323         return dm_stat;
324  }
325#endif
326  return DmtPluginTree::RemoveNode(path);
327
328}
329SYNCML_DM_RET_STATUS_T DmtRWPluginTree::RenameNode( CPCHAR path, CPCHAR szNewNodeName )
330{
331    SYNCML_DM_RET_STATUS_T dm_stat = SYNCML_DM_SUCCESS;
332    PDmtNode ptrNode;
333
334    dm_stat = GetNode( path, ptrNode);
335    if ( dm_stat != SYNCML_DM_SUCCESS)
336        return dm_stat;
337
338    PDmtRWPluginNode pRWNode = (DmtRWPluginNode *) ((DmtNode *)ptrNode);
339
340    return pRWNode->Rename(szNewNodeName);
341}
342
343SYNCML_DM_RET_STATUS_T DmtRWPluginTree::LinkToParentNode( CPCHAR path)
344{
345    SYNCML_DM_RET_STATUS_T dm_stat = SYNCML_DM_SUCCESS;
346    DMString strURI;
347    DMString strKey;
348    PDmtNode ptrNode;
349    DmParseURI( path, strURI, strKey );
350    DMStringVector oChildren;
351
352    dm_stat = this->GetChildNodeNames( strURI.c_str(), oChildren);
353    if ( dm_stat != SYNCML_DM_SUCCESS)
354        return dm_stat;
355
356    if(strURI.length() != 0)
357        oChildren.push_back(strKey.c_str());
358    else
359        oChildren.push_back(path);
360
361    DmtData m_value;
362    dm_stat = m_value.SetNodeValue(oChildren);
363
364    if ( dm_stat != SYNCML_DM_SUCCESS)
365        return dm_stat;
366
367
368    dm_stat = GetNode( strURI.c_str(), ptrNode);
369    if ( dm_stat != SYNCML_DM_SUCCESS)
370        return dm_stat;
371
372    // Turn off logging temporarilly
373    BOOLEAN needLogging= m_Playback;
374    m_Playback = TRUE;
375    dm_stat = ptrNode->SetValue(m_value);
376    m_Playback = needLogging;
377    return dm_stat;
378
379 }
380#ifdef LOB_SUPPORT
381//--------------------------------------------------------------------------------------------
382// FUNCTION        : DmtRWPluginTree::BackupESNdata
383// DESCRIPTION     : Create temporary storage for ESN
384// ARGUMENTS PASSED:
385//
386// RETURN VALUE    :
387//--------------------------------------------------------------------------------------------
388SYNCML_DM_RET_STATUS_T DmtRWPluginTree::BackupESNdata( CPCHAR path)
389{
390  SYNCML_DM_RET_STATUS_T dm_stat = SYNCML_DM_SUCCESS;
391  PDmtNode ptrNode;
392
393  dm_stat = GetNode( path, ptrNode);
394  if ( dm_stat != SYNCML_DM_SUCCESS)
395      return dm_stat;
396
397 if (ptrNode->IsLeaf())
398{
399     if(ptrNode->IsExternalStorageNode())
400     {
401         PDmtRWPluginNode pRWNode = (DmtRWPluginNode *) ((DmtNode *)ptrNode);
402
403        // Backup file already exist?
404        if(pRWNode->GetESNBackupFileName() != NULL)
405            return SYNCML_DM_SUCCESS;
406
407        // Backup ESN data
408         dm_stat = pRWNode->BackupESNData();
409     }
410 }
411 else
412 {
413        DMStringVector mapNodeNames;
414      DMString strVal;
415
416        dm_stat = GetChildNodeNames( path, mapNodeNames );
417
418        if ( dm_stat != SYNCML_DM_SUCCESS )
419           return dm_stat;
420
421        for ( int i = 0; i < mapNodeNames.size(); i++ )
422        {
423        DMString strVal = path;
424        // Is root node?
425        if(strVal.length() != 0)
426              strVal += "/";
427        // Construct child node name
428               strVal += mapNodeNames[i];
429        dm_stat = BackupESNdata(strVal.c_str());
430            if ( dm_stat != SYNCML_DM_SUCCESS )
431            return dm_stat;
432        }
433    }
434    return dm_stat;
435}
436//--------------------------------------------------------------------------------------------
437// FUNCTION        : DmtRWPluginTree::CommitESN
438// DESCRIPTION     : Commit changes for ESN
439// ARGUMENTS PASSED:
440//
441// RETURN VALUE    :
442//--------------------------------------------------------------------------------------------
443SYNCML_DM_RET_STATUS_T DmtRWPluginTree::CommitESN( CPCHAR path)
444{
445  SYNCML_DM_RET_STATUS_T dm_stat = SYNCML_DM_SUCCESS;
446  PDmtNode ptrNode;
447
448  // Any ESN data modified?
449  if(!m_ESNDirty)
450      return dm_stat;
451
452  dm_stat = GetNode( path, ptrNode);
453  if ( dm_stat != SYNCML_DM_SUCCESS)
454      return dm_stat;
455
456 if (ptrNode->IsLeaf())
457{
458     if(ptrNode->IsExternalStorageNode())
459     {
460         PDmtRWPluginNode pRWNode = (DmtRWPluginNode *) ((DmtNode *)ptrNode);
461
462        // Backup ESN data
463         dm_stat = pRWNode->Commit();
464     }
465 }
466 else
467 {
468        DMStringVector mapNodeNames;
469      DMString strVal;
470
471        dm_stat = GetChildNodeNames( path, mapNodeNames );
472
473        if ( dm_stat != SYNCML_DM_SUCCESS )
474           return dm_stat;
475
476        for ( int i = 0; i < mapNodeNames.size(); i++ )
477        {
478        DMString strVal = path;
479        // Is root node?
480        if(strVal.length() != 0)
481                  strVal += "/";
482        // Construct child node name
483               strVal += mapNodeNames[i];
484        dm_stat = CommitESN(strVal.c_str());
485            if ( dm_stat != SYNCML_DM_SUCCESS )
486            return dm_stat;
487        }
488    }
489    return dm_stat;
490}
491//--------------------------------------------------------------------------------------------
492// FUNCTION        : DmtRWPluginTree::IsESNSetComplete
493// DESCRIPTION     : Check if all the ESN setting are done
494// ARGUMENTS PASSED:
495//
496// RETURN VALUE    :
497//--------------------------------------------------------------------------------------------
498BOOLEAN DmtRWPluginTree::IsESNSetComplete(CPCHAR pbURI)
499{
500  SYNCML_DM_RET_STATUS_T dm_stat = SYNCML_DM_SUCCESS;
501  PDmtNode ptrNode;
502  // Any ESN data modified?
503  if(!m_ESNDirty)
504      return TRUE;
505
506  dm_stat = GetNode( pbURI, ptrNode);
507  if ( dm_stat != SYNCML_DM_SUCCESS)
508      return TRUE;
509
510 if (ptrNode->IsLeaf())
511{
512     PDmtRWPluginNode pRWNode = (DmtRWPluginNode *) ((DmtNode *)ptrNode);
513     if(ptrNode->IsExternalStorageNode() && !pRWNode->IsESNSetComplete())
514         return FALSE;
515     else
516         return TRUE;
517 }
518 else
519 {
520        DMStringVector mapNodeNames;
521      DMString strVal;
522
523        dm_stat = GetChildNodeNames( pbURI, mapNodeNames );
524
525        if ( dm_stat != SYNCML_DM_SUCCESS )
526           return TRUE;
527
528        for ( int i = 0; i < mapNodeNames.size(); i++ )
529        {
530        DMString strVal = pbURI;
531              strVal += "/";
532        // Construct child node name
533               strVal += mapNodeNames[i];
534        if(IsESNSetComplete(strVal.c_str()) == FALSE)
535            return FALSE;
536        }
537    }
538    return TRUE;
539}
540#endif
541
542SYNCML_DM_RET_STATUS_T DmtRWPluginTree::CreateLeafNodeInternal( CPCHAR path,
543                                                             PDmtNode& ptrCreatedNode,
544                                                             const DmtData& value ,
545                                                             BOOLEAN isESN)
546{
547    PDmtRWPluginNode pNode;
548    SYNCML_DM_RET_STATUS_T dm_stat;
549
550    pNode=new DmtRWPluginNode();
551    if ( pNode == NULL )
552        return SYNCML_DM_DEVICE_FULL;
553
554     dm_stat = pNode->Init(this, path, value, isESN);
555    if ( dm_stat != SYNCML_DM_SUCCESS )
556        return dm_stat;
557
558    dm_stat = this->SetNode(path, PDmtNode(pNode));
559    if ( dm_stat == SYNCML_DM_SUCCESS )
560        dm_stat = GetNode( path, ptrCreatedNode );
561
562    return dm_stat;
563}
564SYNCML_DM_RET_STATUS_T DmtRWPluginTree::CreateLeafNode(CPCHAR path,
565                              PDmtNode& ptrCreatedNode,
566                              const DmtData& value ,
567                              BOOLEAN isESN)
568{
569    SYNCML_DM_RET_STATUS_T dm_stat;
570
571    dm_stat = LogCommand(SYNCML_DM_PLUGIN_ADD, path, SYNCML_DM_PLUGIN_COMMAND_ON_NODE, NULL);
572    if ( dm_stat != SYNCML_DM_SUCCESS)
573        return dm_stat;
574
575    dm_stat = this ->CreateLeafNodeInternal(path, ptrCreatedNode, value, isESN );
576    if (dm_stat != SYNCML_DM_SUCCESS)
577    {
578        if ( dm_stat == SYNCML_DM_FEATURE_NOT_SUPPORTED )
579            return SYNCML_DM_SUCCESS;
580        else
581            return dm_stat;
582    }
583
584    dm_stat = LinkToParentNode(path);
585    return dm_stat;
586}
587
588SYNCML_DM_RET_STATUS_T DmtRWPluginTree::CreateLeafNode( CPCHAR path,
589                                                            PDmtNode& ptrCreatedNode,
590                                                            const DmtData& value )
591{
592    SYNCML_DM_RET_STATUS_T dm_stat;
593
594    dm_stat = LogCommand(SYNCML_DM_PLUGIN_ADD, path, SYNCML_DM_PLUGIN_COMMAND_ON_NODE, NULL);
595    if ( dm_stat != SYNCML_DM_SUCCESS)
596        return dm_stat;
597
598    dm_stat = this ->CreateLeafNodeInternal(path, ptrCreatedNode, value );
599    if (dm_stat != SYNCML_DM_SUCCESS)
600    {
601        if ( dm_stat == SYNCML_DM_FEATURE_NOT_SUPPORTED )
602            return SYNCML_DM_SUCCESS;
603        else
604            return dm_stat;
605    }
606
607    dm_stat = LinkToParentNode(path);
608    return dm_stat;
609}
610
611SYNCML_DM_RET_STATUS_T DmtRWPluginTree::CreateInteriorNode( CPCHAR path, PDmtNode& ptrCreatedNode )
612{
613    SYNCML_DM_RET_STATUS_T dm_stat;
614    dm_stat = LogCommand(SYNCML_DM_PLUGIN_ADD, path, SYNCML_DM_PLUGIN_COMMAND_ON_NODE, NULL);
615    if ( dm_stat != SYNCML_DM_SUCCESS)
616        return dm_stat;
617
618    DMStringVector oChildren;
619    dm_stat  = this->CreateInteriorNodeInternal(path, ptrCreatedNode, oChildren);
620    if (dm_stat != SYNCML_DM_SUCCESS)
621    {
622        if ( dm_stat == SYNCML_DM_FEATURE_NOT_SUPPORTED )
623            return SYNCML_DM_SUCCESS;
624        else
625            return dm_stat;
626    }
627
628    dm_stat = LinkToParentNode(path);
629    return dm_stat;
630}
631
632SYNCML_DM_RET_STATUS_T DmtRWPluginTree::Begin()
633{
634  #ifdef DM_ATOMIC_SUPPORTED
635  SYNCML_DM_RET_STATUS_T ret_stat = SYNCML_DM_SUCCESS;
636    m_bIsAtomic = TRUE;
637    ret_stat = this->Flush();
638    return ret_stat;
639  #else
640    return SYNCML_DM_FEATURE_NOT_SUPPORTED;
641  #endif
642  }
643
644SYNCML_DM_RET_STATUS_T DmtRWPluginTree::Commit()
645{
646   #ifdef DM_ATOMIC_SUPPORTED
647     SYNCML_DM_RET_STATUS_T ret_stat = SYNCML_DM_SUCCESS;
648
649    ret_stat = this->Flush();
650    m_bIsAtomic = FALSE;
651    return ret_stat;
652   #else
653    return SYNCML_DM_FEATURE_NOT_SUPPORTED;
654   #endif
655
656}
657
658BOOLEAN DmtRWPluginTree::IsAtomic() const
659{
660    return m_bIsAtomic;
661}
662
663SYNCML_DM_RET_STATUS_T DmtRWPluginTree::Flush()
664{
665    SYNCML_DM_RET_STATUS_T dm_stat = SYNCML_DM_SUCCESS;
666#ifdef LOB_SUPPORT
667    // Verify if all ESN setting are complete.
668    if(IsESNSetComplete("") ==  FALSE)
669     return     SYNCML_DM_ESN_SET_NOT_COMPLETE;
670#endif
671    if(this->log != NULL)
672    {
673      this->log->RemoveLog();
674
675        delete this->log;
676        this->log = NULL;
677
678    }
679   if(m_strLogPath != NULL)
680       m_strLogPath = NULL;
681
682#ifdef LOB_SUPPORT
683    // Commit all  ESN changes.
684     dm_stat = CommitESN("");
685     m_ESNDirty = FALSE;
686#endif
687    return dm_stat;
688}
689
690SYNCML_DM_RET_STATUS_T DmtRWPluginTree::Rollback()
691{
692   #ifdef DM_ATOMIC_SUPPORTED
693    SYNCML_DM_RET_STATUS_T dm_stat = SYNCML_DM_SUCCESS;
694    m_Playback = TRUE;
695
696#ifdef TEST_DM_RECOVERY
697    if ((power_fail_point != NULL) && (DmStrcmp(power_fail_point, "PLUGIN_PF2") == 0))
698    {
699        printf("Type Ctrl-C to simulate Power Fail ...\n");
700        sleep(30);
701    }
702#endif
703    if(this->log != NULL)
704    {
705    if(fpLog == NULL)
706            dm_stat = log->playLog(m_strLogPath.c_str());
707    else
708    {    dm_stat = log->playLog();
709        this->log->RemoveLog();
710        fpLog = NULL;
711    }
712        delete this->log;
713        this->log = NULL;
714    }
715   if(m_strLogPath != NULL)
716     m_strLogPath = NULL;
717
718#ifdef TEST_DM_RECOVERY
719    if ((power_fail_point != NULL) && (DmStrcmp(power_fail_point, "PLUGIN_PF3") == 0))
720    {
721        printf("Type Ctrl-C to simulate Power Fail ...\n");
722        sleep(30);
723    }
724#endif
725
726    m_Playback = FALSE;
727    m_ESNDirty = FALSE;
728    m_bIsAtomic = FALSE;
729    m_oAddedNodes.clear();
730    return dm_stat;
731   #else
732   return SYNCML_DM_FEATURE_NOT_SUPPORTED;
733   #endif
734}
735
736
737BOOLEAN DmtRWPluginTree::IsPlaybackMode()
738{
739    return m_Playback;
740}
741
742SYNCML_DM_RET_STATUS_T DmtRWPluginTree::SetPlaybackMode(boolean bPlayback)
743{
744     m_Playback = bPlayback;
745     return SYNCML_DM_SUCCESS;
746}
747
748
749DmtRWPluginNode::~DmtRWPluginNode()
750{
751}
752
753DmtRWPluginNode::DmtRWPluginNode()
754{
755#ifdef LOB_SUPPORT
756  m_LobComplete = TRUE;
757  m_LobDirty = FALSE;
758  m_LobLogging = FALSE;
759  abStorageName = NULL;
760#endif
761}
762
763SYNCML_DM_RET_STATUS_T DmtRWPluginNode::SetTitle( CPCHAR szTitle )
764{
765    SYNCML_DM_RET_STATUS_T dm_stat = SYNCML_DM_SUCCESS;
766    PDmtRWPluginTree ptrTree = (DmtRWPluginTree *) ((DmtPluginTree *)m_ptrTree);
767
768    dm_stat = ptrTree->LogCommand(SYNCML_DM_PLUGIN_REPLACE,
769                                  m_strPath.c_str(),
770                                  SYNCML_DM_PLUGIN_COMMAND_ON_TITLE_PROPERTY,
771                                  (const DmtNode*)this);
772
773    if ( dm_stat != SYNCML_DM_SUCCESS)
774        return dm_stat;
775
776    DmtAttributes oAttr;
777    dm_stat =this->GetAttributes( oAttr );
778
779    if ( dm_stat != SYNCML_DM_SUCCESS)
780        return dm_stat;
781
782    return m_oAttr.SetTitle(szTitle);
783}
784
785SYNCML_DM_RET_STATUS_T DmtRWPluginNode::SetValueInternal( const DmtData& value )
786{
787    m_oData = value;
788    return SYNCML_DM_SUCCESS;
789}
790
791SYNCML_DM_RET_STATUS_T DmtRWPluginNode::SetValue( const DmtData& value )
792{
793    XPL_LOG_DM_PLG_Debug(("Enter DmtRWPluginNode::SetValue..."));
794    PDmtRWPluginTree ptrTree = (DmtRWPluginTree *) ((DmtPluginTree *)m_ptrTree);
795    SYNCML_DM_RET_STATUS_T dm_stat;
796
797    dm_stat= ptrTree->LogCommand(SYNCML_DM_PLUGIN_REPLACE,
798                                 m_strPath.c_str(),
799                                 SYNCML_DM_PLUGIN_COMMAND_ON_NODE,
800                                (const DmtNode *)this);
801    XPL_LOG_DM_PLG_Debug(("LogCommand returns dm_stat=%d", dm_stat));
802
803    if(dm_stat == SYNCML_DM_SUCCESS)
804    {
805    INT32 dataSize;
806      m_oData = value;
807
808      // Get data size
809      dm_stat = m_oData.GetSize(dataSize);
810    XPL_LOG_DM_PLG_Debug(("DmtRWPluginNode::SetValue m_oData.getSize() returns dataSize=%d dm_stat=%d", dataSize, dm_stat));
811      if ( dm_stat != SYNCML_DM_SUCCESS )
812          return dm_stat;
813
814    XPL_LOG_DM_PLG_Debug(("calling m_oAttr.SetSize(%d)", dataSize));
815      m_oAttr.SetSize(dataSize);
816    }
817
818    XPL_LOG_DM_PLG_Debug(("DmtRWPluginNode::SetValue returns dm_stat=%d", dm_stat));
819    return dm_stat;
820}
821
822SYNCML_DM_RET_STATUS_T DmtRWPluginNode::Rename( CPCHAR szNewName )
823{
824    SYNCML_DM_RET_STATUS_T dm_stat = SYNCML_DM_SUCCESS;
825    PDmtRWPluginTree ptrTree = (DmtRWPluginTree *) ((DmtPluginTree *)m_ptrTree);
826
827    DMString strURI;
828    DMString strKey;
829    DmParseURI( m_strPath.c_str(), strURI, strKey );
830
831    DMString strNewURI = strURI;
832    if(strNewURI.length() != 0)
833        strNewURI += "/";
834    strNewURI += szNewName;
835
836    dm_stat = ptrTree->LogCommand(SYNCML_DM_PLUGIN_REPLACE,
837                                  (CPCHAR)strNewURI.c_str(),
838                                  SYNCML_DM_PLUGIN_COMMAND_ON_NAME_PROPERTY,
839                                  (const DmtNode*)this);
840
841    if ( dm_stat != SYNCML_DM_SUCCESS)
842        return dm_stat;
843
844    DMStringVector oChildren;
845
846    dm_stat = m_ptrTree->GetChildNodeNames( strURI.c_str(), oChildren);
847    if ( dm_stat != SYNCML_DM_SUCCESS)
848        return dm_stat;
849
850    // Is the plugin root node?
851    if(strURI.length() == 0)
852    {
853        for ( INT32 i = 0; i < oChildren.size(); i++ )
854        {
855            if (!DmStrcmp(oChildren[i].c_str() , m_strPath.c_str()))
856            {
857                oChildren.remove(i);
858                break;
859            }
860        }
861    }
862    else
863    {
864        for ( INT32 i = 0; i < oChildren.size(); i++ )
865        {
866            if (!DmStrcmp(oChildren[i].c_str() , strKey.c_str()))
867            {
868                oChildren.remove(i);
869                break;
870            }
871        }
872    }
873
874    oChildren.push_back(szNewName);
875    PDmtNode ptrParentNode;
876    DmtData m_value;
877
878    dm_stat = m_value.SetNodeValue(oChildren);
879    if ( dm_stat != SYNCML_DM_SUCCESS)
880        return dm_stat;
881
882    dm_stat = m_ptrTree->GetNode( strURI.c_str(), ptrParentNode);
883    if ( dm_stat != SYNCML_DM_SUCCESS)
884        return dm_stat;
885
886    PDmtRWPluginNode pRWParentNode = (DmtRWPluginNode *) ((DmtNode *)ptrParentNode);
887
888    DmtData oData;
889    dm_stat = pRWParentNode->GetValue( oData );
890    if ( dm_stat != SYNCML_DM_SUCCESS)
891        return dm_stat;
892
893    // Turn off logging temporarilly
894    BOOLEAN needLogging= ptrTree->IsPlaybackMode();
895    ptrTree->SetPlaybackMode(TRUE);
896    dm_stat = pRWParentNode->SetValue(m_value);
897    ptrTree->SetPlaybackMode(needLogging);
898
899    if ( dm_stat != SYNCML_DM_SUCCESS)
900        return dm_stat;
901
902    dm_stat = pRWParentNode->GetValue( oData );
903
904    m_strName = szNewName;
905    if ( szNewName && szNewName[0] )
906    {
907        if ( m_strName == NULL )
908            return SYNCML_DM_DEVICE_FULL;
909    }
910
911    DmtAttributes oAttr;
912    dm_stat = this->GetAttributes( oAttr );
913    if ( dm_stat != SYNCML_DM_SUCCESS)
914        return dm_stat;
915
916    dm_stat = m_oAttr.SetName(szNewName);
917
918    if (dm_stat != SYNCML_DM_SUCCESS)
919        return dm_stat;
920
921    dm_stat = RenameChildNodes(strURI.c_str(), szNewName);
922    return dm_stat;
923}
924
925SYNCML_DM_RET_STATUS_T DmtRWPluginNode::RenameChildNodes( CPCHAR szParentPath, CPCHAR szNodeName )
926{
927    SYNCML_DM_RET_STATUS_T dm_stat = SYNCML_DM_SUCCESS;
928    DMString strURI = szParentPath;
929
930    if(strURI.length() != 0)
931        strURI += "/";
932    strURI += szNodeName;
933
934    dm_stat = m_ptrTree->RemoveNode(m_strPath.c_str());
935    if ( dm_stat != SYNCML_DM_SUCCESS)
936        return dm_stat;
937
938
939    dm_stat = m_ptrTree->SetNode(strURI.c_str(), this);
940    if ( dm_stat != SYNCML_DM_SUCCESS)
941        return dm_stat;
942
943    if ( m_bLeaf )
944    {
945        m_strPath = strURI;
946        return SYNCML_DM_SUCCESS;
947    }
948
949
950    DMStringVector oChildren;
951    dm_stat = m_ptrTree->GetChildNodeNames( strURI.c_str(), oChildren);
952    if ( dm_stat != SYNCML_DM_SUCCESS)
953        return dm_stat;
954
955    for ( int i = 0; i < oChildren.size(); i++ )
956    {
957        DMString strChildPath = m_strPath;
958
959        if (strChildPath.length() !=0)
960            strChildPath += "/";
961
962        strChildPath += oChildren[i];
963
964        PDmtNode ptrNode;
965
966        dm_stat = m_ptrTree->GetNode( strChildPath.c_str(), ptrNode );
967        if ( dm_stat != SYNCML_DM_SUCCESS)
968            return dm_stat;
969
970        PDmtRWPluginNode pRWNode = (DmtRWPluginNode *) ((DmtNode *)ptrNode);
971
972        dm_stat = pRWNode->RenameChildNodes(strURI.c_str(), oChildren[i].c_str());
973        if ( dm_stat != SYNCML_DM_SUCCESS)
974            return dm_stat;
975    }
976    m_strPath = strURI;
977
978    return dm_stat;
979}
980
981#ifdef LOB_SUPPORT
982//--------------------------------------------------------------------------------------------
983// FUNCTION        : DmtRWPluginNode::GetFirstChunk
984// DESCRIPTION     :
985// ARGUMENTS PASSED:
986//
987// RETURN VALUE    : SYNCML_DM_RET_STATUS_T : Returns SYNCML_DM_SUCCESS if success, otherwise fails
988//
989//--------------------------------------------------------------------------------------------
990SYNCML_DM_RET_STATUS_T DmtRWPluginNode::GetFirstChunk(DmtDataChunk&  dmtChunkData)
991{
992   // Only for ESN
993    if(!m_bESN)
994    return SYNCML_DM_COMMAND_NOT_ALLOWED;
995    if(m_LobComplete == FALSE)
996        return SYNCML_DM_ESN_SET_NOT_COMPLETE;
997
998    return SYNCML_DM_SUCCESS;
999}
1000
1001//--------------------------------------------------------------------------------------------
1002// FUNCTION        : DmtRWPluginNode::GetNextChunk
1003// DESCRIPTION     :
1004// ARGUMENTS PASSED:
1005//
1006// RETURN VALUE    : SYNCML_DM_RET_STATUS_T : Returns SYNCML_DM_SUCCESS if success, otherwise fails
1007//
1008//--------------------------------------------------------------------------------------------
1009SYNCML_DM_RET_STATUS_T DmtRWPluginNode::GetNextChunk(DmtDataChunk& dmtChunkData)
1010{
1011  // Only for ESN
1012   if(!m_bESN)
1013     return SYNCML_DM_COMMAND_NOT_ALLOWED;
1014    if(m_LobComplete == FALSE)
1015        return SYNCML_DM_ESN_SET_NOT_COMPLETE;
1016
1017    return SYNCML_DM_SUCCESS;
1018}
1019
1020//--------------------------------------------------------------------------------------------
1021// FUNCTION        : DmtRWPluginNode::SetFirstChunk
1022// DESCRIPTION     :
1023// ARGUMENTS PASSED:
1024//
1025// RETURN VALUE    : SYNCML_DM_RET_STATUS_T : Returns SYNCML_DM_SUCCESS if success, otherwise fails
1026//
1027//--------------------------------------------------------------------------------------------
1028SYNCML_DM_RET_STATUS_T DmtRWPluginNode::SetFirstChunk(DmtDataChunk& dmtChunkData)
1029{
1030  SYNCML_DM_RET_STATUS_T dm_stat = SYNCML_DM_SUCCESS;
1031  PDmtRWPluginTree ptrTree = (DmtRWPluginTree *) ((DmtPluginTree *)m_ptrTree);
1032  // Only for ESN
1033   if(!m_bESN)
1034       return SYNCML_DM_COMMAND_NOT_ALLOWED;
1035
1036  // Need to log the command ?
1037  if(!ptrTree->IsPlaybackMode())
1038  {
1039   if(!m_LobLogging)
1040   {
1041         dm_stat = BackupESNData();
1042         if ( dm_stat != SYNCML_DM_SUCCESS)
1043           return dm_stat;
1044
1045          dm_stat = ptrTree->LogCommand(SYNCML_DM_PLUGIN_REPLACE,
1046                                    m_strPath.c_str(),
1047                                    SYNCML_DM_PLUGIN_COMMAND_ON_LOB_PROPERTY,
1048                                    (const DmtNode*)this);
1049
1050          if ( dm_stat != SYNCML_DM_SUCCESS)
1051          return dm_stat;
1052    m_LobLogging = TRUE;
1053   }
1054
1055  m_LobComplete = FALSE;
1056  m_LobDirty = TRUE;
1057  //Set flag in the plugin tree
1058  ptrTree->SetESNDirty();
1059  }
1060  return dm_stat;
1061}
1062
1063//--------------------------------------------------------------------------------------------
1064// FUNCTION        : DmtRWPluginNode::SetNextChunk
1065// DESCRIPTION     :
1066// ARGUMENTS PASSED:
1067//
1068// RETURN VALUE    : SYNCML_DM_RET_STATUS_T : Returns SYNCML_DM_SUCCESS if success, otherwise fails
1069//
1070//--------------------------------------------------------------------------------------------
1071SYNCML_DM_RET_STATUS_T DmtRWPluginNode::SetNextChunk(DmtDataChunk& dmtChunkData)
1072{
1073  PDmtRWPluginTree ptrTree = (DmtRWPluginTree *) ((DmtPluginTree *)m_ptrTree);
1074 // Only for ESN and SetFirstChunk() is invoked.
1075 if(!m_bESN )
1076      return SYNCML_DM_COMMAND_NOT_ALLOWED;
1077 // Need to log the command ?
1078 if(!ptrTree->IsPlaybackMode())
1079 {
1080     if(!m_LobDirty ||m_LobComplete)
1081      return SYNCML_DM_INCOMPLETE_COMMAND;
1082 }
1083    return SYNCML_DM_SUCCESS;
1084}
1085
1086//--------------------------------------------------------------------------------------------
1087// FUNCTION        : DmtRWPluginNode::SetLastChunk
1088// DESCRIPTION     :
1089// ARGUMENTS PASSED:
1090//
1091// RETURN VALUE    : SYNCML_DM_RET_STATUS_T : Returns SYNCML_DM_SUCCESS if success, otherwise fails
1092//
1093//--------------------------------------------------------------------------------------------
1094SYNCML_DM_RET_STATUS_T DmtRWPluginNode::SetLastChunk(DmtDataChunk& dmtChunkData)
1095{
1096   PDmtRWPluginTree ptrTree = (DmtRWPluginTree *) ((DmtPluginTree *)m_ptrTree);
1097  // Only for ESN and SetFirstChunk() is invoked.
1098   if(!m_bESN )
1099        return SYNCML_DM_COMMAND_NOT_ALLOWED;
1100
1101   if(!ptrTree->IsPlaybackMode())
1102   {
1103       if(!m_LobDirty ||m_LobComplete)
1104        return SYNCML_DM_INCOMPLETE_COMMAND;
1105
1106       m_LobComplete = TRUE;
1107   }
1108   return SYNCML_DM_SUCCESS;
1109}
1110
1111//--------------------------------------------------------------------------------------------
1112// FUNCTION        : DmtRWPluginNode::Commit
1113// DESCRIPTION     : Commit changes for an ESN
1114// ARGUMENTS PASSED:
1115//
1116// RETURN VALUE    : SYNCML_DM_RET_STATUS_T : Returns SYNCML_DM_SUCCESS if success, otherwise fails
1117//
1118//--------------------------------------------------------------------------------------------
1119SYNCML_DM_RET_STATUS_T DmtRWPluginNode::Commit()
1120{
1121   SYNCML_DM_RET_STATUS_T dm_stat = SYNCML_DM_SUCCESS;
1122   // Only for ESN
1123   if(m_bESN)
1124   {
1125       m_LobComplete = TRUE;
1126       m_LobDirty = FALSE;
1127       m_LobLogging = FALSE;
1128    // Remove temporary storage file
1129    if(abStorageName.length() != 0)
1130    {
1131        DMFileHandler sourceHandle(abStorageName);
1132        dm_stat = sourceHandle.open(XPL_FS_FILE_RDWR);
1133        if(dm_stat == SYNCML_DM_SUCCESS)
1134                sourceHandle.deleteFile();
1135        abStorageName = NULL;
1136    }
1137   }
1138   return SYNCML_DM_SUCCESS;
1139}
1140
1141//--------------------------------------------------------------------------------------------
1142// FUNCTION        : DmtRWPluginNode::Delete
1143// DESCRIPTION     : Delete the node
1144// ARGUMENTS PASSED:
1145//
1146// RETURN VALUE    : SYNCML_DM_RET_STATUS_T : Returns SYNCML_DM_SUCCESS if success, otherwise fails
1147//
1148//--------------------------------------------------------------------------------------------
1149SYNCML_DM_RET_STATUS_T DmtRWPluginNode::Delete()
1150{
1151   return SYNCML_DM_SUCCESS;
1152}
1153
1154//--------------------------------------------------------------------------------------------
1155// FUNCTION        : DmtRWPluginNode::BackupESNData
1156// DESCRIPTION     : Backup ESN data to temporary file
1157// ARGUMENTS PASSED:
1158//
1159// RETURN VALUE    : SYNCML_DM_RET_STATUS_T : Returns SYNCML_DM_SUCCESS if success, otherwise fails
1160//
1161//--------------------------------------------------------------------------------------------
1162SYNCML_DM_RET_STATUS_T DmtRWPluginNode::BackupESNData()
1163{
1164 SYNCML_DM_RET_STATUS_T dm_stat = SYNCML_DM_SUCCESS;
1165 PDmtRWPluginTree ptrTree = (DmtRWPluginTree *) ((DmtPluginTree *)m_ptrTree);
1166 DmtDataChunk chunkData;
1167 UINT32 getLen;
1168 UINT8 *bufp;
1169
1170  if(!m_bESN || m_LobLogging)
1171    return SYNCML_DM_SUCCESS;
1172
1173  DmtAttributes oAttr;
1174  dm_stat =this->GetAttributes( oAttr );
1175  // Is the ESN empty
1176  if(oAttr.GetSize() == 0)
1177  {
1178    abStorageName = NULL;
1179    return SYNCML_DM_SUCCESS;
1180  }
1181
1182 // No internal file created yet
1183 if(abStorageName.length() == 0) {
1184       dm_stat = DMFileHandler::createTempESNFileName(abStorageName);
1185       if(dm_stat != SYNCML_DM_SUCCESS)
1186           return dm_stat;
1187 }
1188 DMFileHandler tempLogFileHandler(abStorageName);
1189 dm_stat = tempLogFileHandler.open(XPL_FS_FILE_WRITE);
1190 if(dm_stat != SYNCML_DM_SUCCESS)
1191     return    SYNCML_DM_IO_FAILURE;
1192
1193 // Allocate chunk buffer
1194 if(chunkData.AllocateChunkBuffer() != SYNCML_DM_SUCCESS)
1195    return  SYNCML_DM_DEVICE_FULL;
1196
1197 dm_stat = GetFirstChunk(chunkData);
1198 if( dm_stat != SYNCML_DM_SUCCESS)
1199     return dm_stat;
1200 chunkData.GetReturnLen(getLen);
1201 chunkData.GetChunkData(&bufp);  // the chunk data is available
1202
1203  while (true)
1204 {
1205      // Get the last chunk of data
1206      if (getLen == 0)
1207              break;
1208      if(tempLogFileHandler.seek(XPL_FS_SEEK_END, 0) != SYNCML_DM_SUCCESS)
1209      {
1210         dm_stat =    SYNCML_DM_IO_FAILURE;
1211        break;
1212      }
1213      if(tempLogFileHandler.write((CPCHAR)bufp, getLen) != SYNCML_DM_SUCCESS)
1214      {
1215        dm_stat =    SYNCML_DM_IO_FAILURE;
1216        break;
1217      }
1218      dm_stat = GetNextChunk(chunkData);
1219      if( dm_stat != SYNCML_DM_SUCCESS)
1220          break;
1221      chunkData.GetReturnLen(getLen);
1222      chunkData.GetChunkData(&bufp);
1223  }
1224
1225  if(dm_stat != SYNCML_DM_SUCCESS)
1226  {     tempLogFileHandler.deleteFile();
1227      abStorageName = NULL;
1228  }
1229  else
1230      tempLogFileHandler.close();
1231
1232 //Set flag in the plugin tree
1233 ptrTree->SetESNDirty();
1234 return  dm_stat;
1235}
1236//--------------------------------------------------------------------------------------------
1237// FUNCTION        : DmtRWPluginNode::RestoreESNData
1238// DESCRIPTION     : Restore ESN data from temporary file
1239// ARGUMENTS PASSED:
1240//
1241// RETURN VALUE    : SYNCML_DM_RET_STATUS_T : Returns SYNCML_DM_SUCCESS if success, otherwise fails
1242//
1243//--------------------------------------------------------------------------------------------
1244SYNCML_DM_RET_STATUS_T DmtRWPluginNode::RestoreESNData( CPCHAR szBackupFileName )
1245{
1246 SYNCML_DM_RET_STATUS_T dm_stat = SYNCML_DM_SUCCESS;
1247 UINT32 totalSize;
1248 DmtDataChunk chunkData;
1249 int setLen = 0;
1250 int offset = 0;
1251 bool isFirstChunk = true;
1252 bool isLastChunk = false;
1253 UINT8 *bufp;
1254
1255 if(!m_bESN )
1256     return SYNCML_DM_SUCCESS;
1257
1258 int chunksize = chunkData.GetChunkSize();
1259
1260  m_LobComplete = TRUE;
1261  m_LobDirty = FALSE;
1262  m_LobLogging = FALSE;
1263
1264  // No internal storage file
1265  if(DmStrlen(szBackupFileName) == 0)
1266  {
1267      dm_stat = SetFirstChunk(chunkData);
1268     if(dm_stat != SYNCML_DM_SUCCESS)
1269         return dm_stat;
1270      dm_stat = SetLastChunk(chunkData);
1271     abStorageName = NULL;
1272
1273     return dm_stat;
1274  }
1275
1276  if(!XPL_FS_Exist(szBackupFileName))
1277    return SYNCML_DM_SUCCESS;
1278
1279
1280 DMFileHandler tempFileHandler(szBackupFileName);
1281 dm_stat = tempFileHandler.open(XPL_FS_FILE_RDWR);
1282 if(dm_stat != SYNCML_DM_SUCCESS)
1283     return    SYNCML_DM_IO_FAILURE;
1284 totalSize = tempFileHandler.size();
1285
1286 // Allocate chunk buffer
1287 if(chunkData.AllocateChunkBuffer() != SYNCML_DM_SUCCESS)
1288    return  SYNCML_DM_DEVICE_FULL;
1289
1290 chunkData.GetChunkData(&bufp);  // the chunk data is available
1291
1292
1293 while(!isLastChunk)
1294 {     setLen =  totalSize- offset;
1295     if(setLen > 0)
1296     {
1297         if(setLen > chunksize)
1298             setLen = chunksize;
1299     }
1300     else
1301         isLastChunk = true;
1302
1303     if(tempFileHandler.seek(XPL_FS_SEEK_SET, offset) != SYNCML_DM_SUCCESS)
1304         return  SYNCML_DM_IO_FAILURE;
1305     if(tempFileHandler.read(bufp, setLen) != SYNCML_DM_SUCCESS)
1306         return  SYNCML_DM_IO_FAILURE;
1307
1308     dm_stat = chunkData.SetChunkData((const UINT8 *)bufp, setLen);
1309     if(dm_stat != SYNCML_DM_SUCCESS)
1310         return    dm_stat;
1311
1312     if(isFirstChunk)
1313     {
1314         dm_stat = SetFirstChunk(chunkData);
1315         isFirstChunk = false;
1316     }
1317     else
1318     {     if(!isLastChunk)
1319             dm_stat = SetNextChunk(chunkData);
1320         else
1321             dm_stat = SetLastChunk(chunkData);
1322     }
1323     if(dm_stat != SYNCML_DM_SUCCESS)
1324         return    dm_stat;
1325
1326        offset += setLen;
1327    }
1328
1329    totalSize = tempFileHandler.deleteFile();
1330    abStorageName = NULL;
1331    return dm_stat;
1332}
1333
1334#endif
1335