Home | History | Annotate | Download | only in src
      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 "SyncML_DM_WBXMLArchive.H"
     18 #include "SyncML_DM_Reader.H"
     19 #include "xpl_Logger.h"
     20 #include "dm_tree_class.H"
     21 #include "dmprofile.h"
     22 #include "dm_uri_utils.h"
     23 
     24 /* The DEFAULT_FILE_HEADER field represents the start of a standard WBXML document
     25  * for standards compliance and for the purpose of file size efficiency.
     26  *
     27  * The first 3 bytes are WBXML standard values:
     28  *     version is always 1 byte.
     29  *     publicid - We assume the public ID is <=127, which only takes 1 byte
     30  *                for its mb_uint32 encoding.
     31  *     charset - 0x6A is the code for UTF-8; 1 byte for mb_uint32 encoding
     32  * The 4th byte is the mb_uint32 length of the optional string table that follows;
     33  * we will not have a string table, so the length is zero and no table follows.
     34  *
     35  * The purpose of the string table is to store common strings that occur multiple
     36  * times in the document, and thus save space by referring to them. This is a
     37  * possible future enhancement.
     38  */
     39 const UINT8 SyncML_DM_WBXMLArchive::DEFAULT_FILE_HEADER[] = {
     40       WBXML_VERSION, PUBLIC_ID, CHARSET, 0x00
     41   };
     42 
     43 /* The wchar_t standard and handy L"string"; usage are not supported by the ARM compiler.*/
     44 const char SyncML_DM_WBXMLArchive::FILE_EXTENSION[] = ".wbxml";
     45 
     46 /*==================================================================================================
     47 
     48 Function:    SyncML_DM_WBXMLArchive::SyncML_DM_WBXMLArchive
     49 
     50 Description: Constructor method that creates a log and sets up the path and uri of the archive
     51 
     52 ==================================================================================================*/
     53 SyncML_DM_WBXMLArchive::SyncML_DM_WBXMLArchive(CEnv* env, CPCHAR pURI, CPCHAR path)
     54         : SyncML_DM_Archive( env, pURI, path),
     55           m_pEnv( env )
     56 {
     57     lastSavedTime = 0;
     58 #ifdef LOB_SUPPORT
     59     commitLog = NULL;
     60 #endif
     61 
     62     if (!m_strWFSFileName.empty() && m_strWFSFileName.length() > 0) {
     63         m_permission = 0;
     64         // initialize permission mask
     65         if (XPL_FS_CheckPermission(m_strWFSFileName, XPL_FS_RDONLY_MODE)) {
     66             m_permission = XPL_FS_RDONLY_MODE;
     67         }
     68         if (XPL_FS_CheckPermission(m_strWFSFileName, XPL_FS_RDWR_MODE)) {
     69             m_permission |= (XPL_FS_RDWR_MODE|XPL_FS_WRONLY_MODE|XPL_FS_RDWR_MODE|
     70                              XPL_FS_CREAT_MODE|XPL_FS_TRUNC_MODE|XPL_FS_APPEND_MODE);
     71         }
     72     }
     73     XPL_LOG_DM_TMN_Debug(("m_permission initialized to %d, path %s, uri=%s\n",  m_permission, m_strWFSFileName.c_str(), pURI ));
     74 }
     75 
     76 /*==================================================================================================
     77 
     78 Function:    SyncML_DM_WBXMLArchive::~SyncML_DM_WBXMLArchive
     79 
     80 Description: The SyncML_DM_WBXMLArchive class deconstructor.
     81 
     82 ==================================================================================================*/
     83 SyncML_DM_WBXMLArchive::~SyncML_DM_WBXMLArchive()
     84 {
     85 #ifdef LOB_SUPPORT
     86   // Remove  commit log handler
     87   if(commitLog != NULL)
     88   {
     89 	commitLog->CloseLog();
     90 	delete commitLog;
     91 	commitLog = NULL;
     92   }
     93 #endif
     94 }
     95 
     96 /*==================================================================================================
     97 
     98 Function:    SyncML_DM_WBXMLArchive::serialize
     99 
    100 Description: Serialization method takes a tree as an argument serializes to the file system
    101 
    102 ==================================================================================================*/
    103 SYNCML_DM_RET_STATUS_T
    104 SyncML_DM_WBXMLArchive::serialize(DMTree* tree)
    105 {
    106     SYNCML_DM_SERIALIZATION_STATUS_T ser_ret_stat;
    107 
    108 #ifdef DM_PROFILER_ENABLED
    109     DMString strCaption = "serialize ";
    110     strCaption += getURI(); strCaption += ", \"";
    111     strCaption += m_path; strCaption += "\"";
    112     DM_PROFILE( strCaption );
    113 #endif
    114 
    115     /* Create the path string for the temp file */
    116     if (this->rootTreeNode==NULL)
    117         return SYNCML_DM_SKIP_SUBTREE;
    118 
    119     tree->InitSerializationList(this->rootTreeNode);
    120 
    121     /* Path + Extension + null */
    122     DMString strTempFilePath = m_strWFSFileName;
    123     strTempFilePath += DMFileHandler::TEMP_FILE_EXTENSION;
    124 
    125     /* Acquire a handle representation of the file */
    126     DMFileHandler fileHandle(strTempFilePath.c_str());
    127 
    128     /* Open the file for writing */
    129 
    130     SYNCML_DM_RET_STATUS_T retstat = fileHandle.open(XPL_FS_FILE_WRITE);
    131 
    132     if(retstat == SYNCML_DM_COMMAND_NOT_ALLOWED) {
    133         return retstat;
    134     }
    135     else if (retstat != SYNCML_DM_SUCCESS) {
    136         return SYNCML_DM_IO_FAILURE;
    137     }
    138 
    139     /* Create a WBXMLWriter utility class for handling the data */
    140     SyncML_DM_WBXMLWriter writer(&fileHandle);
    141 
    142     /* Write the default file header, which contains the WBXML version, public ID,
    143        charset (UTF-8), lookup table length, and lookup table */
    144     if(writer.writeData((UINT8 *)DEFAULT_FILE_HEADER,
    145                         (UINT8)sizeof(DEFAULT_FILE_HEADER)) != SYNCML_DM_SUCCESS) {
    146         return SYNCML_DM_IO_FAILURE;
    147     }
    148 
    149     /* Write the MgmtTree start tag */
    150     if(writer.writeByte(SyncML_DM_WBXMLArchive::TREE_START_TAG |
    151                         SyncML_DM_WBXMLArchive::TAG_CONTENT_MASK) != SYNCML_DM_SUCCESS) {
    152         return SYNCML_DM_IO_FAILURE;
    153     }
    154 
    155     /* Create a URI object for the currURI
    156       * For the purposes of conserving memory allocation cycles, we assume the worst
    157       * case URI length + 1 for the nil terminator, and we will reuse this same
    158       * buffer as the loop runs, putting in a nil terminator where its needed.
    159       */
    160     DMNode * pRetNode = NULL;
    161     /* Loop on the nodes returned by the tree and node manager */
    162     INT32 nEndTagsNumber = 0;
    163     while((ser_ret_stat = tree->GetSerializationListNextItem(&pRetNode, nEndTagsNumber)) == SYNCML_DM_SERIALIZATION_SUCCESS)
    164     {
    165 
    166         // write "end" tags
    167         while( nEndTagsNumber > 0 ) {
    168           nEndTagsNumber--;
    169 
    170           if(writer.writeByte(SyncML_DM_WBXMLArchive::END_TAG) != SYNCML_DM_SUCCESS)
    171               return  SYNCML_DM_IO_FAILURE;
    172         }
    173 #ifdef LOB_SUPPORT
    174 	// Special case for ESN
    175 	if(pRetNode->IsESN())
    176 	{
    177 		SYNCML_DM_RET_STATUS_T retStatus;
    178 		 // Convert to	ESN pointer
    179 		DMDefaultESN *tempESN = reinterpret_cast< DMDefaultESN *>(pRetNode);
    180 		// Close internal files
    181 		retStatus = tempESN->CloseInternalFile();
    182 		if(retStatus != SYNCML_DM_SUCCESS)
    183 				return retStatus;
    184 	}
    185 #endif
    186 
    187         if(writer.writeNode(pRetNode) != SYNCML_DM_SUCCESS) {
    188             XPL_LOG_DM_TMN_Error((" SYNCML_DM_IO_FAILURE on %s\n",  (const char *)m_pURI ));
    189             return  SYNCML_DM_IO_FAILURE;
    190         }
    191 
    192         if ( pRetNode->opiInSync() )
    193         {
    194              UINT8 flag = pRetNode->getFlags();
    195              flag &= ~( DMNode::enum_NodeOPISyncUptodate );
    196              pRetNode->setFlags(flag);
    197         }
    198 
    199     }/* End while */
    200 
    201     /* Ensure the while() terminated as expected */
    202     if (ser_ret_stat == SYNCML_DM_TREE_TRAVERSING_OVER) {
    203         /* We have to write the end tag of the last node, as well as any
    204          * parent nodes that also ended. currURI tells up how many (one
    205          * for each / still in it)
    206          */
    207         while( nEndTagsNumber > 0 ) {
    208           nEndTagsNumber--;
    209 
    210           if(writer.writeByte(SyncML_DM_WBXMLArchive::END_TAG) != SYNCML_DM_SUCCESS)
    211               return SYNCML_DM_IO_FAILURE;
    212         }
    213     } else /* ser_ret_stat == SYNCML_DM_SERIALIZATION_FAIL */
    214     {
    215         fileHandle.close();
    216         return SYNCML_DM_FAIL;
    217     }
    218     /* Write the end tag for the root node, then end tag for the MgmtTree */
    219     UINT8 endTags[2] = { SyncML_DM_WBXMLArchive::END_TAG, SyncML_DM_WBXMLArchive::END_TAG };
    220 
    221     if(writer.writeData(&endTags[0], 2) != SYNCML_DM_SUCCESS)
    222     {
    223         fileHandle.close();
    224         return SYNCML_DM_IO_FAILURE;
    225     }
    226     /* Close the file */
    227     if (fileHandle.close() != SYNCML_DM_SUCCESS)
    228         return SYNCML_DM_IO_FAILURE;
    229 
    230     return SYNCML_DM_SUCCESS;
    231 }
    232 
    233 /*==================================================================================================
    234 
    235 
    236 Function:    SyncML_DM_WBXMLArchive::deserialize
    237 
    238 Description: Deserializes a tree in the filesystem to the memory tree
    239 
    240 ==================================================================================================*/
    241 
    242 SYNCML_DM_RET_STATUS_T
    243 SyncML_DM_WBXMLArchive::deserialize(DMTree * pTree,
    244                                     BOOLEAN bIsReload)
    245 {
    246     SYNCML_DM_RET_STATUS_T ret_stat = SYNCML_DM_SUCCESS;
    247 
    248 #ifdef DM_PROFILER_ENABLED
    249     DMString strCaption = "deserialize ";
    250     strCaption += getURI(); strCaption += ", \"";
    251     strCaption += m_path; strCaption += "\"";
    252     DM_PROFILE( strCaption );
    253 #endif
    254 
    255     if ( !rootTreeNode )
    256         return SYNCML_DM_FAIL;
    257 
    258     oEventLogger.Reset();
    259 
    260     if ( !rootTreeNode->IsSkeletonNode() )
    261     {
    262         if ( bIsReload )
    263 	  m_pTree->UnloadArchive(rootTreeNode);
    264         else
    265 	  return SYNCML_DM_SUCCESS;
    266     }
    267 
    268     DMPluginManager & oPluginManager = m_pTree->GetPluginManager();
    269 
    270     ret_stat = deserializeFile( pTree, m_strWFSFileName, true );
    271 
    272     if ( ret_stat == SYNCML_DM_FILE_NOT_FOUND )
    273         setWritableExist( FALSE );
    274     else
    275     {
    276         setWritableExist( TRUE );
    277         return oPluginManager.UpdatePluginNodes(m_pURI);
    278     }
    279 
    280     for ( int nFS = 0; nFS < m_pEnv->GetRFSCount(); nFS++ )
    281     {
    282         DMString sFile;
    283         m_pEnv->GetRFSFullPath(nFS,m_path,sFile);
    284         if ( deserializeFile( pTree, sFile, false ) == SYNCML_DM_SUCCESS )
    285             ret_stat = SYNCML_DM_SUCCESS; // at least one file was successfully loaded
    286     }
    287 
    288    return oPluginManager.UpdatePluginNodes(m_pURI);
    289 }
    290 
    291 SYNCML_DM_RET_STATUS_T SyncML_DM_WBXMLArchive::deserializeFile(
    292     DMTree* pTree,
    293     CPCHAR szFileName,
    294     BOOLEAN bWFS)
    295 {
    296     if (!XPL_FS_Exist(szFileName))
    297         return SYNCML_DM_FILE_NOT_FOUND;
    298 
    299     SYNCML_DM_RET_STATUS_T ret_stat = SYNCML_DM_SUCCESS;
    300 
    301     /* Create a file handle for the file to be deserialized */
    302     DMFileHandler fileHandle(szFileName);
    303     SYNCML_DM_RET_STATUS_T openstat = fileHandle.open(XPL_FS_FILE_READ);
    304 
    305     /* If file cannot be opened, leave now */
    306     if(openstat == SYNCML_DM_COMMAND_NOT_ALLOWED) {
    307         return openstat;
    308     }
    309     else if (openstat != SYNCML_DM_SUCCESS) {
    310         return SYNCML_DM_FILE_NOT_FOUND;    /* Assume this is the underlying reason */
    311     }
    312 
    313     m_permission |= XPL_FS_RDONLY_MODE;
    314 
    315     /* Create a reader utility class for the reading of tree data */
    316     SyncML_DM_WBXMLReader reader(&fileHandle);
    317 
    318     /* Working variable */
    319     UINT8 bYte;
    320 
    321     /* Read a WBXML header from the file */
    322     if(reader.readHeader() != SYNCML_DM_SUCCESS)
    323     {
    324         fileHandle.close();
    325         return SYNCML_DM_IO_FAILURE;
    326     }
    327 
    328     /* Read and verify the MgmtTree start tag */
    329     if(reader.readByte(&bYte) != SYNCML_DM_SUCCESS)
    330     {
    331         fileHandle.close();
    332         return SYNCML_DM_IO_FAILURE;
    333     }
    334     if(bYte != (TREE_START_TAG | TAG_CONTENT_MASK))
    335     {
    336         fileHandle.close();
    337         return SYNCML_DM_IO_FAILURE;
    338     }
    339 
    340     /* Read the first byte of data, expected to be END_TAG or NODE_START_TAG.
    341     * The byte read will be parsed in the upcoming loop.
    342     * If the byte is not the NODE_START_TAG with content, there is no
    343     * tree to parse or there is an error (we assume error here).
    344     */
    345     if(reader.readByte(&bYte) != SYNCML_DM_SUCCESS
    346           || bYte != (SyncML_DM_WBXMLArchive::NODE_START_TAG
    347                       | SyncML_DM_WBXMLArchive::TAG_CONTENT_MASK))
    348     {
    349         fileHandle.close();
    350         return SYNCML_DM_IO_FAILURE;
    351     }
    352 
    353     /* The properties data structure */
    354     DMAddNodeProp props;
    355 
    356     DMNode* pNode = rootTreeNode->GetParent(); // can be null for '.'; otherwise is valid parent
    357 
    358     /* Loop until an internal break occurs (hopefully, not until the last END_TAG */
    359     while(1)
    360     {
    361         /* If the read byte is an END_TAG... */
    362         if(bYte == END_TAG)
    363         {
    364 
    365             if ( pNode == rootTreeNode )
    366                 break; // end of subtree
    367 
    368             if ( !pNode || !pNode->GetParent() ){
    369                 XPL_LOG_DM_TMN_Error((" ! Unexpected condition (node is null) inside deserialize\n"));
    370                 fileHandle.close();
    371                 return SYNCML_DM_TREE_CORRUPT;  // unexpected condition - looks like extra "end tag"
    372             }
    373 
    374             pNode = pNode->GetParent();
    375 
    376             /* Get the next byte after the END_TAG */
    377             ret_stat=reader.readByte(&bYte);
    378             if(ret_stat != SYNCML_DM_SUCCESS) {
    379                 XPL_LOG_DM_TMN_Error((" ! Error ret_stat=%d\n", ret_stat));
    380                 fileHandle.close();
    381                 return SYNCML_DM_IO_FAILURE;
    382             }
    383         }
    384         else
    385             if(bYte == (NODE_START_TAG | TAG_CONTENT_MASK))
    386             {
    387 
    388                 /* This method reads in the node property data as well as
    389                 * the byte that signaled the end of the node.
    390                 * It allocates a props structure we are responsible for,
    391                 * It also sets props->pbURI to NULL.
    392                 */
    393                 if(reader.readNode(&props, &bYte) != SYNCML_DM_SUCCESS)
    394                 {
    395                     fileHandle.close();
    396                     return SYNCML_DM_IO_FAILURE;
    397                 }
    398 
    399                 /* Add the node to the tree */
    400 
    401                 ret_stat = pTree->AddNode(&pNode, props);
    402 
    403                 if (ret_stat != SYNCML_DM_SUCCESS)
    404                     break;
    405 
    406             }
    407             else
    408             {
    409                 /* Invalid byte read */
    410                 ret_stat = SYNCML_DM_TREE_CORRUPT;
    411                 break;
    412             }
    413     }/* End while */
    414 
    415     fileHandle.close();
    416     XPL_LOG_DM_TMN_Debug(("End of deserialize ret_stat=%d\n", ret_stat));
    417 
    418     //set time stamp to emmory file
    419     if ( bWFS )
    420         serializeDone();
    421 
    422     return ret_stat;
    423 }
    424 
    425 /*==================================================================================================
    426 
    427 Function:    SyncML_DM_WBXMLArchive::getLastModifiedTime
    428 
    429 Description: Retrieves the last modification time of the archive
    430 
    431 ==================================================================================================*/
    432 
    433 XPL_CLK_CLOCK_T
    434 SyncML_DM_WBXMLArchive::getLastModifiedTime()
    435 {
    436     XPL_CLK_CLOCK_T lastModified=XPL_FS_GetModTime(m_strWFSFileName);
    437     return lastModified;
    438 }
    439 
    440 XPL_CLK_CLOCK_T SyncML_DM_WBXMLArchive::getLastSavedTime()
    441 {
    442     return lastSavedTime;
    443 }
    444 
    445 void SyncML_DM_WBXMLArchive::serializeDone()
    446 {
    447     lastSavedTime=XPL_FS_GetModTime(m_strWFSFileName);
    448     oEventLogger.OnTreeSaved();
    449 }
    450 
    451 // returns TRUE if permission is allowed
    452 BOOLEAN
    453 SyncML_DM_WBXMLArchive::verifyPermission(XPL_FS_OPEN_MODE_T permission) const
    454 {
    455     // XPL_LOG_DM_TMN_Debug(("m_permission=%d, filename=%s\n", m_permission, m_strWFSFileName.c_str()));
    456     return (m_permission & permission);
    457 }
    458 
    459 
    460 #ifdef LOB_SUPPORT
    461 /*==================================================================================================
    462 
    463 Function:    SyncML_DM_WBXMLArchive::commitESN
    464 
    465 Description: Commit all changes for ESN
    466 
    467 ==================================================================================================*/
    468 SYNCML_DM_RET_STATUS_T
    469 SyncML_DM_WBXMLArchive::commitESN(DMTree* tree)
    470 {
    471     SYNCML_DM_SERIALIZATION_STATUS_T ser_ret_stat;
    472     SYNCML_DM_RET_STATUS_T retStatus = SYNCML_DM_SUCCESS;
    473 
    474    //Remove commit log file
    475    if(commitLog != NULL)
    476    {
    477     //Commit log file name =  Path + "commit" + null
    478     DMString strTempFilePath = m_strWFSFileName;
    479     strTempFilePath += DMFileHandler::COMMIT_LOG_EXTENSION;
    480     commitLog->playLog(strTempFilePath.c_str());
    481     delete  commitLog;
    482     commitLog  = NULL;
    483 
    484    /* Create the path string for the temp file */
    485     if (this->rootTreeNode==NULL)
    486         return SYNCML_DM_SKIP_SUBTREE;
    487 
    488     tree->InitSerializationList(this->rootTreeNode);
    489 
    490     DMNode * pRetNode = NULL;
    491     /* Loop on the nodes returned by the tree and node manager */
    492     INT32 nEndTagsNumber = 0;
    493     while((ser_ret_stat = tree->GetSerializationListNextItem(&pRetNode, nEndTagsNumber)) == SYNCML_DM_SERIALIZATION_SUCCESS)
    494     {
    495 	// Special case for ESN
    496 	if(pRetNode->IsESN())
    497 	{
    498 		 // Convert to  ESN pointer
    499 		 DMDefaultESN *tempESN = reinterpret_cast< DMDefaultESN *>(pRetNode);
    500 		// Call commit command handler
    501 		retStatus = tempESN->Commit();
    502 		if(retStatus != SYNCML_DM_SUCCESS)
    503 			return retStatus;
    504 	}
    505     }/* End while */
    506    }
    507    return SYNCML_DM_SUCCESS;
    508 }
    509 /*==================================================================================================
    510 
    511 Function:    SyncML_DM_WBXMLArchive::rollback
    512 
    513 Description: Rollback all changes for ESN
    514 
    515 ==================================================================================================*/
    516 SYNCML_DM_RET_STATUS_T
    517 SyncML_DM_WBXMLArchive::rollbackESN(DMTree* tree)
    518 {
    519     SYNCML_DM_SERIALIZATION_STATUS_T ser_ret_stat;
    520     SYNCML_DM_RET_STATUS_T retStatus = SYNCML_DM_SUCCESS;
    521 
    522    //Remove commit log file
    523    if(commitLog != NULL)
    524    {
    525 	commitLog->RemoveLog();
    526 	  delete  commitLog;
    527 	  commitLog  = NULL;
    528 
    529   /* Create the path string for the temp file */
    530     if (this->rootTreeNode==NULL)
    531         return SYNCML_DM_SKIP_SUBTREE;
    532 
    533     tree->InitSerializationList(this->rootTreeNode);
    534 
    535     DMNode * pRetNode = NULL;
    536     /* Loop on the nodes returned by the tree and node manager */
    537     INT32 nEndTagsNumber = 0;
    538     while((ser_ret_stat = tree->GetSerializationListNextItem(&pRetNode, nEndTagsNumber)) == SYNCML_DM_SERIALIZATION_SUCCESS)
    539     {
    540 	// Special case for ESN
    541 	if(pRetNode->IsESN())
    542 	{
    543 		 // Convert to  ESN pointer
    544 		 DMDefaultESN *tempESN = reinterpret_cast< DMDefaultESN *>(pRetNode);
    545 		// Call rollback command handler
    546 		retStatus = tempESN->Rollback();
    547 		if(retStatus != SYNCML_DM_SUCCESS)
    548 			return retStatus;
    549 	}
    550     }/* End while */
    551    }
    552    return SYNCML_DM_SUCCESS;
    553 }
    554 /*==================================================================================================
    555 
    556 Function:    SyncML_DM_WBXMLArchive::GetCommitLogHandler
    557 
    558 Description: Retrieves the commit log handler
    559 
    560 ==================================================================================================*/
    561 SyncML_Commit_Log*  SyncML_DM_WBXMLArchive::GetCommitLogHandler()
    562 {
    563   	if(commitLog == NULL)
    564 	{	commitLog = new SyncML_Commit_Log();
    565 		if(this->commitLog != NULL)
    566 		{
    567 			//Commit log file name =  Path + "commit" + null
    568 			DMString strTempFilePath = m_strWFSFileName;
    569 			strTempFilePath += DMFileHandler::COMMIT_LOG_EXTENSION;
    570 			if(this->commitLog->InitLog(strTempFilePath.c_str())  != SYNCML_DM_SUCCESS)
    571 			{
    572 				delete commitLog;
    573 				commitLog = NULL;
    574 			}
    575 		}
    576   	}
    577 	return commitLog;
    578 }
    579 /*==================================================================================================
    580 
    581 Function:    SyncML_DM_WBXMLArchive::CloseCommitLog
    582 
    583 Description: Close the commit log file
    584 
    585 ==================================================================================================*/
    586 SYNCML_DM_RET_STATUS_T  SyncML_DM_WBXMLArchive::CloseCommitLog()
    587 {
    588   SYNCML_DM_RET_STATUS_T ret_stat = SYNCML_DM_SUCCESS;
    589   if(commitLog != NULL)
    590  	ret_stat = commitLog->CloseLog();
    591   return ret_stat;
    592 }
    593 /*==================================================================================================
    594 
    595 Function:    SyncML_DM_WBXMLArchive::PlayCommitLog
    596 
    597 Description: Free the commit log handler
    598 
    599 ==================================================================================================*/
    600 SYNCML_DM_RET_STATUS_T  SyncML_DM_WBXMLArchive::PlayCommitLog()
    601 {
    602   SYNCML_DM_RET_STATUS_T ret_stat = SYNCML_DM_SUCCESS;
    603   if(commitLog == NULL)
    604 	  GetCommitLogHandler();
    605   if(commitLog != NULL)
    606   {
    607 	commitLog->playLog();
    608 	commitLog->RemoveLog();
    609 	delete commitLog;
    610 	commitLog = NULL;
    611   }
    612   return ret_stat;
    613 }
    614 #endif
    615