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