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 /*==================================================================================================
     18 
     19     Source Name: DMMetaDataManager.cc
     20 
     21     General Description: Implementation of the DMMetaDataManager class
     22 
     23 ==================================================================================================*/
     24 
     25 #include "dmStringUtil.h"
     26 #include "dm_tree_util.h"
     27 #include "dm_uri_utils.h"
     28 #include "xpl_Logger.h"
     29 #include "xpl_dm_Manager.h"
     30 #include "dm_tree_plugin_util.H"
     31 #include "dm_tree_plugin_root_node_class.H"
     32 #include "dmMetaDataManager.h"
     33 #include "xpl_Regex.h"
     34 
     35 CPCHAR  DMMetaDataManager::m_pFloatPattern[] =
     36 {
     37    "^[+-]?[0-9]+[.]?[0-9]*[Ee]?[+-]?[0-9]*$", // dEn or den
     38    "^[+-,0-9,Ee,.]*[Ee+-.]$", // ends in character 'E' 'e'  '+'  '-'
     39    "^[^Ee]+[+-][0-9]$"  // '' is not following 'E' or 'e'
     40 };
     41 
     42 CPCHAR  DMMetaDataManager::m_pDatePattern[] =
     43 {
     44    "^[0-9]{4}-[0-9]{2}-[0-9]{2}$", // YYYY-MM-DD
     45    "^[0-9]{4}-[0-9]{2}$", // YYYY-MM
     46    "^[0-9]{4}-[0-9]{3}$", //YYY-DDD
     47    "^[0-9]{4}-[W][0-9]{2}-[1-7]$",  //YYYY-Wxx-d
     48    "^[0-9]{4}-[W][0-9]{2}$",  //YYYY-Wxx
     49    "^[0-9]{8}$", //YYYYMMDD
     50    "^[0-9]{6}$",  //YYYYMM
     51    "^[0-9]{7}$", //YYYDDD
     52    "^[0-9]{4}$", // YYYY
     53    "^[0-9]{4}[W][0-9]{2}[1-7]$", //YYYYWxxd
     54    "^[0-9]{4}[W][0-9]{2}$" //YYYYWxx
     55 };
     56 
     57 CPCHAR DMMetaDataManager::m_pTimePattern[] =
     58 {
     59    "^[0-9]{2}:[0-9]{2}:[0-9]{2}$", //hh:mm:ss
     60    "^[0-9]{2}:[0-9]{2}$", //hh:mm
     61    "^[0-9]{6}$", //hhmmss
     62    "^[0-9]{4}$", //hhmm
     63    "^[0-9]{2}$",  //hh
     64    "^[0-9]{2}:[0-9]{2}:[0-9]{2}Z$", //hh:mm:ssZ
     65    "^[0-9]{2}:[0-9]{2}:[0-9]{2}[+-][0-9]{2}:[0-9]{2}$" //hh:mm:sshh:mm
     66 };
     67 
     68 DMMetaDataManager::DMMetaDataManager()
     69   : m_pEnv( NULL ),
     70     m_pTree( NULL ),
     71     m_bIsLoad( FALSE )
     72 {
     73 }
     74 
     75 SYNCML_DM_RET_STATUS_T DMMetaDataManager::Init( CEnv* env, DMTree* tree )
     76 {
     77   if( !env || !tree ) return SYNCML_DM_FAIL;
     78   m_pEnv  = env;
     79   m_pTree = tree;
     80   return SYNCML_DM_SUCCESS;
     81 }
     82 
     83 
     84 void DMMetaDataManager::DeInit()
     85 {
     86   UnLoad();
     87   m_pEnv = NULL;
     88   m_pTree = NULL;
     89 }
     90 
     91 DMMetaDataManager::~DMMetaDataManager()
     92 {
     93   DeInit();
     94 }
     95 
     96 
     97 void
     98 DMMetaDataManager::UnLoad()
     99 {
    100    if(m_bIsLoad == FALSE)
    101     return;
    102 
    103    XPL_LOG_DM_TMN_Debug(("UNLOAD\n"));
    104 #ifndef DM_STATIC_FILES
    105    UINT32 size = m_oDDFInfo.size();
    106    for (UINT32 i=0; i<size; i++)
    107    {
    108         DMFileHandler * pFile = (DMFileHandler*)m_oDDFInfo[i];
    109         delete pFile;
    110    }
    111 #endif
    112    m_oDDFInfo.clear();
    113    m_bIsLoad = FALSE;
    114    m_oLastNodeLocator.Init();
    115 }
    116 
    117 CPCHAR
    118 DMMetaDataManager::GetNodeName(DMNode* pNode, CPCHAR szURI)
    119 {
    120     if ( pNode->isPlugin() )
    121     {
    122         DMURI uri(FALSE,szURI);
    123         return uri.getLastSegment();
    124     } else
    125         return pNode->abNodeName.GetBuffer();
    126 }
    127 
    128 
    129 BOOLEAN
    130 DMMetaDataManager::VerifyChildDependency(CPCHAR szNodeName,
    131                                           CPCHAR szURI,
    132                                           CPCHAR szOrigName,
    133                                           SYNCML_DM_MDF_CBACK callBackSoft,
    134                                           SYNCML_DM_MDF_CBACK callBackHard,
    135                                           SYNCML_DM_ACCESS_TYPE_T accessType)
    136 {
    137     DMMetaDataNode oNodeMDF;
    138     DMConstraints *pConstraints = NULL;
    139     SYNCML_DM_RET_STATUS_T ret_status = SYNCML_DM_SUCCESS;
    140 
    141     ret_status = GetNode(szURI, FALSE, oNodeMDF);
    142     if ( ret_status != SYNCML_DM_SUCCESS )
    143     {
    144         return FALSE;
    145     }
    146     if ( oNodeMDF.m_nNodeFormat == SYNCML_DM_FORMAT_TEST )
    147         return TRUE;
    148 
    149     pConstraints = oNodeMDF.GetConstraints();
    150     if ( !pConstraints )
    151         return TRUE;
    152 
    153     if( pConstraints->m_psChild != 0 )
    154     {
    155         if( !VerifyDependency(szNodeName,pConstraints->m_psChild,szOrigName,callBackHard) )
    156             return FALSE;
    157     }
    158     if( pConstraints->m_psDepend != 0 )
    159     {
    160         if( !VerifyDependency(szNodeName,pConstraints->m_psDepend,szOrigName,callBackSoft) )
    161             return FALSE;
    162     }
    163     return TRUE;
    164 
    165 }
    166 
    167 
    168 
    169 SYNCML_DM_RET_STATUS_T
    170 DMMetaDataManager::VerifyDeleteParameters(DMNode* pNode, CPCHAR szURI)
    171 
    172 {
    173     DMMetaDataNode oNodeMDF;
    174     CPCHAR strNodeName;
    175     SYNCML_DM_RET_STATUS_T ret_status = SYNCML_DM_SUCCESS;
    176 
    177     strNodeName = GetNodeName(pNode,szURI);
    178     if(strNodeName == NULL)
    179         return SYNCML_DM_COMMAND_FAILED;
    180     if (!VerifyChildDependency(strNodeName,szURI,NULL,ClearNodeValue,CheckFieldInUse,SYNCML_DM_DELETE_ACCESS_TYPE))
    181            return SYNCML_DM_COMMAND_FAILED;
    182     return ret_status;
    183 }
    184 
    185 
    186 
    187 SYNCML_DM_RET_STATUS_T
    188 DMMetaDataManager::VerifyData(DMAddData & oAddData)
    189 
    190 {
    191 
    192     if(  !oAddData.m_oData.getSize() )
    193         return SYNCML_DM_SUCCESS;
    194 
    195     switch ( oAddData.m_nFormat )
    196     {
    197         case SYNCML_DM_FORMAT_INT:
    198             if ( !IsDigit(oAddData.m_oData) )
    199                  return SYNCML_DM_UNSUPPORTED_MEDIATYPE_FORMAT;
    200             break;
    201 
    202         case SYNCML_DM_FORMAT_FLOAT:
    203             if ( !IsFloat(oAddData.m_oData) )
    204                   return SYNCML_DM_UNSUPPORTED_MEDIATYPE_FORMAT;
    205             break;
    206 
    207          case SYNCML_DM_FORMAT_DATE:
    208             if ( !IsDate(oAddData.m_oData) )
    209                   return SYNCML_DM_UNSUPPORTED_MEDIATYPE_FORMAT;
    210             break;
    211 
    212          case SYNCML_DM_FORMAT_TIME:
    213              if ( !IsTime(oAddData.m_oData) )
    214                   return SYNCML_DM_UNSUPPORTED_MEDIATYPE_FORMAT;
    215              break;
    216 
    217           case SYNCML_DM_FORMAT_BOOL:
    218              if ( !IsBoolean(oAddData.m_oData) )
    219                  return SYNCML_DM_UNSUPPORTED_MEDIATYPE_FORMAT;
    220              break;
    221     }
    222     return SYNCML_DM_SUCCESS;
    223 }
    224 
    225 
    226 
    227 SYNCML_DM_RET_STATUS_T
    228 DMMetaDataManager::VerifyFormat(const DMMetaDataNode & oNodeMDF,
    229                                                 DMAddData & oAddData)
    230 
    231 {
    232 
    233     if ( m_pTree->IsVersion_12() == FALSE  )
    234     {
    235         if ( oAddData.m_nFormat ==  SYNCML_DM_FORMAT_FLOAT  ||
    236              oAddData.m_nFormat ==  SYNCML_DM_FORMAT_DATE  ||
    237              oAddData.m_nFormat ==  SYNCML_DM_FORMAT_TIME  )
    238         {
    239             XPL_LOG_DM_TMN_Debug(("DMMetaDataManager::VerifyFormat: format not supported: float,data, time\n"));
    240             return SYNCML_DM_UNSUPPORTED_MEDIATYPE_FORMAT;
    241         }
    242     }
    243 
    244 
    245     if ( oNodeMDF.m_nNodeFormat == SYNCML_DM_FORMAT_TEST )
    246         return SYNCML_DM_SUCCESS;
    247 
    248     if ( oAddData.m_nFormat != SYNCML_DM_FORMAT_INVALID &&
    249          oAddData.m_nFormat != SYNCML_DM_FORMAT_NULL )
    250     {
    251         if (oNodeMDF.m_nNodeFormat != oAddData.m_nFormat)
    252         {
    253             XPL_LOG_DM_TMN_Debug(("DMMetaDataManager::VerifyFormat: unsupported mediatype: %d != %d\n", oNodeMDF.m_nNodeFormat, oAddData.m_nFormat));
    254             return SYNCML_DM_UNSUPPORTED_MEDIATYPE_FORMAT;
    255         }
    256     }
    257 
    258     if( oNodeMDF.VerifyMimeType(oAddData.getType()) != TRUE )
    259     {
    260         XPL_LOG_DM_TMN_Debug(("DMMetaDataManager::VerifyFormat: verify mime type failed\n"));
    261         return SYNCML_DM_UNSUPPORTED_MEDIATYPE_FORMAT;
    262     }
    263 
    264     return SYNCML_DM_SUCCESS;
    265 
    266 }
    267 
    268 
    269 SYNCML_DM_RET_STATUS_T
    270 DMMetaDataManager::VerifyInteger(const DMBuffer & oData)
    271 {
    272 
    273      if ( !oData.getSize() )
    274         return SYNCML_DM_SUCCESS;
    275 
    276      INT32 int_value = 0;
    277      char numbuf[MAX_INT_STRING_LENGTH];
    278 
    279      int_value = DmAtoi((CPCHAR)oData.getBuffer());
    280 
    281      DmSprintf( numbuf, "%d", int_value );
    282      if ( DmStrcmp(numbuf, (CPCHAR)oData.getBuffer()) != 0 )
    283         return SYNCML_DM_UNSUPPORTED_MEDIATYPE_FORMAT;
    284 
    285      return SYNCML_DM_SUCCESS;
    286 
    287 }
    288 
    289 
    290 
    291 SYNCML_DM_RET_STATUS_T
    292 DMMetaDataManager::VerifyInteriorNodeConstraints(DMConstraints *pConstraints,
    293                                                                       CPCHAR szNodeName)
    294 
    295 {
    296     SYNCML_DM_RET_STATUS_T dm_stat = SYNCML_DM_SUCCESS;
    297 
    298     if( pConstraints->m_nnMaxLen < DmStrlen(szNodeName) )
    299 #ifdef DM_NO_REGEX
    300         return SYNCML_DM_REQUEST_ENTITY_TOO_LARGE;
    301 #else
    302         return SYNCML_DM_URI_TOO_LONG;
    303 #endif
    304 
    305     if(VerifynValues(pConstraints, szNodeName) != TRUE)
    306         return SYNCML_DM_COMMAND_FAILED;
    307 
    308     if( pConstraints->m_psnRegexp != NULL)
    309         dm_stat = VerifyRegExp(pConstraints->m_psnRegexp,szNodeName);
    310 
    311     return dm_stat;
    312 }
    313 
    314 
    315 SYNCML_DM_RET_STATUS_T
    316 DMMetaDataManager::SetDefaultValue(const DMMetaDataNode & oNodeMDF,
    317                                                      DMAddData & oAddData)
    318 {
    319     DMConstraints *pConstraints = NULL;
    320 
    321     pConstraints = oNodeMDF.GetConstraints();
    322 
    323     if ( pConstraints == NULL )
    324         return SYNCML_DM_SUCCESS;
    325 
    326     if( !pConstraints->IsDefaultSet() )
    327         return(SYNCML_DM_UNSUPPORTED_MEDIATYPE_FORMAT);
    328 
    329     if(oNodeMDF.m_nNodeFormat == SYNCML_DM_FORMAT_INVALID)
    330         return(SYNCML_DM_UNSUPPORTED_MEDIATYPE_FORMAT);
    331 
    332     DMString strDefaultValue;
    333     pConstraints->GetDefaultString(strDefaultValue);
    334     if ( strDefaultValue.GetBuffer() )
    335     {
    336         oAddData.m_oData.assign(strDefaultValue);
    337         if ( oAddData.m_oData.getBuffer() == NULL )
    338              return SYNCML_DM_DEVICE_FULL;
    339     }
    340     oAddData.m_nFormat = oNodeMDF.m_nNodeFormat;
    341     return SYNCML_DM_SUCCESS;
    342 
    343 }
    344 
    345 
    346 SYNCML_DM_RET_STATUS_T
    347 DMMetaDataManager::VerifyLeafNodeConstraints(const DMMetaDataNode & oNodeMDF,
    348                                      DMAddData & oAddData)
    349 
    350 {
    351     DMConstraints *pConstraints = NULL;
    352     SYNCML_DM_RET_STATUS_T dm_stat = SYNCML_DM_SUCCESS;
    353 
    354     pConstraints = oNodeMDF.GetConstraints();
    355 
    356     if ( pConstraints == NULL )
    357         return SYNCML_DM_SUCCESS;
    358 
    359 #ifdef LOB_SUPPORT
    360     // ESN only support SYNCML_DM_FORMAT_BIN and  SYNCML_DM_FORMAT_STRING
    361     if(oNodeMDF.IsESN())
    362     {
    363          if ( oAddData.m_nFormat != SYNCML_DM_FORMAT_CHR  &&
    364               oAddData.m_nFormat != SYNCML_DM_FORMAT_BIN)
    365               return(SYNCML_DM_UNSUPPORTED_MEDIATYPE_FORMAT);
    366     }
    367 #endif
    368 
    369     if(pConstraints->m_nMaxLen < oAddData.m_oData.getSize())
    370         return SYNCML_DM_REQUEST_ENTITY_TOO_LARGE;
    371 
    372     if (pConstraints->m_nMinLen > oAddData.m_oData.getSize())
    373         return SYNCML_DM_UNSUPPORTED_MEDIATYPE_FORMAT;
    374 
    375     if ( oAddData.m_nFormat == SYNCML_DM_FORMAT_INT )
    376     {
    377         INT32 int_value = 0;
    378         if ( oAddData.m_oData.getSize() )
    379             int_value = DmAtoi(oAddData.getCharData());
    380 
    381         if((pConstraints->m_nMin > int_value) || (pConstraints->m_nMax < int_value))
    382             return SYNCML_DM_COMMAND_FAILED;
    383 
    384     }
    385 
    386     if (pConstraints->m_psValues != NULL )
    387     {
    388         if ( oAddData.m_nFormat != SYNCML_DM_FORMAT_NULL )
    389         {
    390             if(!VerifyValues(pConstraints, oAddData.m_nFormat, oAddData.m_oData))
    391                 return SYNCML_DM_COMMAND_FAILED;
    392         }
    393         else
    394              return SYNCML_DM_COMMAND_FAILED;
    395     }
    396 
    397     if ( pConstraints->m_psForeignKey != NULL )
    398     {
    399         if ( oAddData.m_nFormat != SYNCML_DM_FORMAT_NULL )
    400         {
    401             if(!VerifyForeignKey(pConstraints, oAddData.m_oData))
    402                 return SYNCML_DM_COMMAND_FAILED;
    403         }
    404         else
    405              return SYNCML_DM_COMMAND_FAILED;
    406     }
    407 
    408     if( pConstraints->m_psRegexp != NULL)
    409     {
    410         if ( oAddData.m_nFormat != SYNCML_DM_FORMAT_NULL )
    411         {
    412              dm_stat = VerifyRegExp(pConstraints->m_psRegexp,oAddData.getCharData());
    413              if (dm_stat != SYNCML_DM_SUCCESS)
    414                 return(SYNCML_DM_COMMAND_FAILED);
    415          }
    416          else
    417                return SYNCML_DM_COMMAND_FAILED;
    418     }
    419 
    420     return dm_stat;
    421 }
    422 
    423 
    424 SYNCML_DM_RET_STATUS_T
    425 DMMetaDataManager::VerifyConstraints(const DMMetaDataNode & oNodeMDF,
    426                                      DMNode* pNode,
    427                                      CPCHAR szNodeName,
    428                                      DMAddData & oAddData)
    429 
    430 {
    431     DMConstraints *pConstraints = NULL;
    432     SYNCML_DM_RET_STATUS_T dm_stat = SYNCML_DM_SUCCESS;
    433 
    434     pConstraints = oNodeMDF.GetConstraints();
    435 
    436     if ( pConstraints == NULL )
    437         return SYNCML_DM_SUCCESS;
    438 
    439     dm_stat = VerifyInteriorNodeConstraints(pConstraints,szNodeName);
    440     if ( dm_stat != SYNCML_DM_SUCCESS )
    441         return dm_stat;
    442 
    443 
    444     if ( oNodeMDF.m_nNodeFormat == SYNCML_DM_FORMAT_TEST )
    445         return SYNCML_DM_SUCCESS;
    446 
    447     if ( oAddData.m_nFormat == SYNCML_DM_FORMAT_INVALID )
    448         dm_stat = SetDefaultValue(oNodeMDF,oAddData);
    449     else
    450         if ( oAddData.m_nFormat != SYNCML_DM_FORMAT_NODE )
    451             dm_stat = VerifyLeafNodeConstraints(oNodeMDF, oAddData);
    452         else
    453             if ( oAddData.m_nFormat == SYNCML_DM_FORMAT_NULL && oAddData.m_oData.getSize() )
    454                 return SYNCML_DM_COMMAND_FAILED;
    455 
    456     return dm_stat;
    457 }
    458 
    459 
    460 
    461 SYNCML_DM_RET_STATUS_T
    462 DMMetaDataManager::VerifyParameters(const DMMetaDataNode & oNodeMDF,
    463                                      DMNode* pNode,
    464                                      CPCHAR szNodeName,
    465                                      DMAddData & oAddData)
    466 
    467 {
    468     DMConstraints *pConstraints = NULL;
    469     SYNCML_DM_RET_STATUS_T dm_stat = SYNCML_DM_SUCCESS;
    470 
    471     dm_stat = VerifyFormat(oNodeMDF,oAddData);
    472     if ( dm_stat != SYNCML_DM_SUCCESS )
    473     {
    474         XPL_LOG_DM_TMN_Debug(("DMMetaDataManager::VerifyParameters: verify format failed \n"));
    475         return dm_stat;
    476     }
    477 
    478     dm_stat = VerifyData(oAddData);
    479     if ( dm_stat != SYNCML_DM_SUCCESS )
    480     {
    481         XPL_LOG_DM_TMN_Debug(("DMMetaDataManager::VerifyParameters: verify data failed \n"));
    482         return dm_stat;
    483     }
    484 
    485     pConstraints = oNodeMDF.GetConstraints();
    486 
    487     if ( !pConstraints )
    488     {
    489        if ( oAddData.m_nFormat == SYNCML_DM_FORMAT_INVALID ||
    490             oAddData.m_nFormat == SYNCML_DM_FORMAT_NULL )
    491             oAddData.m_nFormat = oNodeMDF.m_nNodeFormat;
    492     }
    493 
    494     if ( oAddData.m_nFormat == SYNCML_DM_FORMAT_INT )
    495     {
    496         dm_stat = VerifyInteger(oAddData.m_oData);
    497         if ( dm_stat != SYNCML_DM_SUCCESS )
    498         {
    499              XPL_LOG_DM_TMN_Debug(("DMMetaDataManager::VerifyParameters: verify Integer failed \n"));
    500              return dm_stat;
    501         }
    502     }
    503 
    504     if ( pConstraints )
    505         dm_stat = VerifyConstraints(oNodeMDF,pNode,szNodeName,oAddData);
    506     if ( dm_stat != SYNCML_DM_SUCCESS )
    507     {
    508          XPL_LOG_DM_TMN_Debug(("DMMetaDataManager::VerifyParameters: verify Constraits failed \n"));
    509     }
    510 
    511     return dm_stat;
    512 }
    513 
    514 
    515 
    516 SYNCML_DM_RET_STATUS_T
    517 DMMetaDataManager::VerifyReplaceParameters(DMNode* pNode,
    518                                      CPCHAR szURI,
    519                                      DMAddData & oAddData,
    520                                      CPCHAR szOrigName)
    521 
    522 {
    523     DMMetaDataNode oNodeMDF;
    524     CPCHAR strNodeName;
    525     SYNCML_DM_RET_STATUS_T ret_status = SYNCML_DM_SUCCESS;
    526 
    527     XPL_LOG_DM_TMN_Debug(("Enter to DMMetaDataManager::VerifyReplaceParameters %s\n",szURI));
    528 
    529     ret_status = GetNode(szURI, FALSE, oNodeMDF);
    530     XPL_LOG_DM_TMN_Error(("From VerifyReplaceParameters(): Call to  GetNode() returns %d \n", ret_status));
    531 
    532     if(ret_status == SYNCML_DM_NOT_FOUND)
    533         return SYNCML_DM_COMMAND_NOT_ALLOWED;
    534 
    535     else if(ret_status != SYNCML_DM_SUCCESS)
    536         return SYNCML_DM_COMMAND_FAILED;
    537 
    538 #ifdef LOB_SUPPORT
    539     // ESN only only be created using empty data
    540     if(oNodeMDF.IsESN() && oAddData.m_oData.getSize() )
    541         return(SYNCML_DM_COMMAND_FAILED);
    542 #endif
    543 
    544     strNodeName = GetNodeName(pNode,szURI);
    545     if(strNodeName == NULL){
    546         XPL_LOG_DM_TMN_Error(("From VerifyReplaceParameters(): call getNode()....  strNodeName == NULL"));
    547         return SYNCML_DM_COMMAND_FAILED;
    548     }
    549     ret_status = VerifyParameters(oNodeMDF,pNode,strNodeName,oAddData);
    550     XPL_LOG_DM_TMN_Error(("From VerifyReplaceParameters(): Call to  VerifyParameters() returns %d \n", ret_status));
    551 
    552     if(ret_status != SYNCML_DM_SUCCESS)
    553         return ret_status;
    554 
    555     if(szOrigName == NULL)
    556         return ret_status;
    557 
    558     if ( oNodeMDF.m_nNodeFormat == SYNCML_DM_FORMAT_TEST )
    559         return SYNCML_DM_SUCCESS;
    560 
    561     if (!VerifyChildDependency(strNodeName, szURI, szOrigName, ResetNodeValue, ResetNodeValue,
    562             SYNCML_DM_REPLACE_ACCESS_TYPE)) {
    563         XPL_LOG_DM_TMN_Error(("From VerifyReplaceParameters(): Call to VerifyChildDependency() returns FALSE"));
    564         return SYNCML_DM_COMMAND_FAILED;
    565     }
    566     return ret_status;
    567 }
    568 
    569 SYNCML_DM_RET_STATUS_T
    570 DMMetaDataManager::VerifyAddParameters(DMNode* pNode,
    571                                      DMAddData & oAddData,
    572                                      DMToken & oAutoNodes,
    573                                      BOOLEAN & bNodeGetAccess)
    574 {
    575     DMMetaDataNode oNodeMDF;
    576     CPCHAR strNodeName;
    577     DMConstraints *pConstraints = NULL;
    578     SYNCML_DM_RET_STATUS_T ret_status = SYNCML_DM_SUCCESS;
    579 
    580     XPL_LOG_DM_TMN_Debug(("Enter to DMMetaDataManager::VerifyAddParameters %s\n",oAddData.getURI()));
    581 
    582     ret_status = GetNode(oAddData.getURI(), FALSE, oNodeMDF);
    583     if(ret_status != SYNCML_DM_SUCCESS)
    584     {
    585         XPL_LOG_DM_TMN_Debug(("DMMetaDataManager::VerifyAddParameters: failed to get node MDF.\n"));
    586         return SYNCML_DM_COMMAND_FAILED;
    587     }
    588 
    589 #ifdef LOB_SUPPORT
    590     // ESN only only be created using empty data
    591     if(oNodeMDF.IsESN() && oAddData.m_oData.getSize() )
    592     {
    593         XPL_LOG_DM_TMN_Debug(("DMMetaDataManager::VerifyAddParameters: ESN, but not empty\n"));
    594         return(SYNCML_DM_COMMAND_FAILED);
    595     }
    596 #endif
    597     strNodeName = GetNodeName(pNode,oAddData.getURI());
    598     if(strNodeName == NULL)
    599         return SYNCML_DM_COMMAND_FAILED;
    600     ret_status = VerifyParameters(oNodeMDF,pNode,strNodeName,oAddData);
    601     if(ret_status != SYNCML_DM_SUCCESS)
    602     {
    603        XPL_LOG_DM_TMN_Debug(("DMMetaDataManager::VerifyAddParameters: failed to get verify parameters.\n"));
    604        return ret_status;
    605     }
    606 
    607    bNodeGetAccess = oNodeMDF.VerifyAccessType(SYNCML_DM_GET_ACCESS_TYPE);
    608 
    609     if (oNodeMDF.m_nNodeFormat == SYNCML_DM_FORMAT_NODE )
    610     {
    611         pConstraints = oNodeMDF.GetConstraints();
    612         if ( pConstraints && pConstraints->m_psAutoNodes )
    613         {
    614             oAutoNodes.assign(pConstraints->m_psAutoNodes);
    615             if ( !oAutoNodes.getBuffer() )
    616                 XPL_LOG_DM_TMN_Debug(("DMMetaDataManager::VerifyAddParameters: failed to get verify Access Type.\n"));
    617                 return SYNCML_DM_COMMAND_FAILED;
    618         }
    619     }
    620     return ret_status;
    621 }
    622 
    623 
    624 
    625 BOOLEAN
    626 DMMetaDataManager::IsDigit(const DMBuffer & oData)
    627 {
    628    INT32 start_index = 0;
    629    UINT8 *pData = oData.getBuffer();
    630 
    631    if (pData[0] == '-' || pData[0] == '+')
    632      start_index++;
    633 
    634    for (UINT32 i=start_index; i<oData.getSize(); i++)
    635    {
    636       if (pData[i]<0x30 || pData[i]>0x39)
    637         return FALSE;
    638    }
    639 
    640    return TRUE;
    641 }
    642 
    643 
    644 BOOLEAN
    645 DMMetaDataManager::IsBoolean(const DMBuffer & oData)
    646 {
    647     INT32 size = oData.getSize();
    648     UINT8 *pData = oData.getBuffer();
    649 
    650     if(size < 4 && size > 5)
    651          return FALSE;
    652 
    653     char str[6];
    654 
    655     for (int i=0; i<size; i++)
    656        str[i] = DmTolower((char)pData[i]);
    657     str[size] = SYNCML_DM_NULL;
    658 
    659     if ( DmStrcmp(str,"true") == 0 || DmStrcmp(str, "false") == 0 )
    660        return TRUE;
    661 
    662     return FALSE;
    663 }
    664 
    665 
    666 BOOLEAN
    667 DMMetaDataManager::IsFloat(const DMBuffer & oData)
    668 {
    669 #ifdef DM_NO_REGEX
    670 
    671     return ::XPL_RG_Comp( XPL_RG_PATTERN_IS_FLOAT, (CPCHAR)oData.getBuffer() )
    672               ? SYNCML_DM_SUCCESS
    673               : SYNCML_DM_UNSUPPORTED_MEDIATYPE_FORMAT;
    674 #else
    675 
    676    // Validate float string with XML 1.0 regular express
    677    if (VerifyRegExp((CPCHAR)m_pFloatPattern[0], (CPCHAR)oData.getBuffer())
    678           != SYNCML_DM_SUCCESS)
    679    {
    680       return FALSE;
    681    }
    682    else
    683    {
    684       // Float string ends with 'E', 'e', '+' '-' or '.' character.
    685       if (VerifyRegExp((CPCHAR)m_pFloatPattern[1], (CPCHAR)oData.getBuffer())
    686           == SYNCML_DM_SUCCESS)
    687       {
    688          return FALSE;
    689       }
    690       else
    691       {
    692           // '+' or '-' character is not next to 'E' or 'e'.
    693          if (VerifyRegExp((CPCHAR)m_pFloatPattern[2], (CPCHAR)oData.getBuffer())
    694                 == SYNCML_DM_SUCCESS)
    695          {
    696              return FALSE;
    697          }
    698          else
    699          {
    700              return TRUE;
    701          }
    702       }
    703    }
    704 
    705    return TRUE;
    706 
    707 #endif
    708 }
    709 
    710 
    711 BOOLEAN
    712 DMMetaDataManager::IsDate(const DMBuffer & oData)
    713 {
    714 #ifdef DM_NO_REGEX
    715     return ::XPL_RG_Comp( XPL_RG_PATTERN_IS_DATE, (CPCHAR)oData.getBuffer() )
    716               ? SYNCML_DM_SUCCESS
    717               : SYNCML_DM_UNSUPPORTED_MEDIATYPE_FORMAT;
    718 #else
    719 
    720    for (UINT8 i=0; i<sizeof(m_pDatePattern)/sizeof(int); i++)
    721    {
    722       if (VerifyRegExp(m_pDatePattern[i],(CPCHAR)oData.getBuffer())==SYNCML_DM_SUCCESS)
    723       {
    724          CPCHAR pData = (CPCHAR)oData.getBuffer();
    725          switch (i)
    726          {
    727             case 0:  // YYYY-MM-DD
    728                if ((DmStrncmp(pData+5,"01",2)<0 || DmStrncmp(pData+5,"12",2)>0)||
    729                    (DmStrncmp(pData+8,"01",2)<0 || DmStrncmp(pData+8,"31",2)>0))
    730                   return FALSE;
    731                else
    732                   return TRUE;
    733             case 1:  // YYYY-MM
    734                if ((DmStrncmp(pData+5,"01",2)<0 || DmStrncmp(pData+5,"12",2)>0))
    735                   return FALSE;
    736                else
    737                   return TRUE;
    738             case 2:  // YYYY-DDD
    739                if ((DmStrncmp(pData+5,"001",3)<0 || DmStrncmp(pData+5,"366",3)>0))
    740                   return FALSE;
    741                else
    742                   return TRUE;
    743             case 3:  // YYYY-Wxx-d
    744             case 4:  // YYYY-Wxx
    745                if ((DmStrncmp(pData+6,"01",2)<0 || DmStrncmp(pData+6,"52",2)>0))
    746                   return FALSE;
    747                else
    748                   return TRUE;
    749             case 5:  // YYYYMMDD
    750                if ((DmStrncmp(pData+4,"01",2)<0 || DmStrncmp(pData+4,"12",2)>0)||
    751                    (DmStrncmp(pData+6,"01",2)<0 || DmStrncmp(pData+6,"31",2)>0))
    752                   return FALSE;
    753                else
    754                   return TRUE;
    755             case 6:  // YYYYMM
    756                if ((DmStrncmp(pData+4,"01",2)<0 || DmStrncmp(pData+4,"12",2)>0))
    757                   return FALSE;
    758                else
    759                   return TRUE;
    760             case 7:  // YYYYDDD
    761                if ((DmStrncmp(pData+4,"001",3)<0 || DmStrncmp(pData+4,"365",3)>0))
    762                   return FALSE;
    763                else
    764                   return TRUE;
    765             case 8:  // YYYY
    766                   return TRUE;
    767             case 9:  // YYYYWxxd
    768             case 10:  // YYYYWxx
    769                if ((DmStrncmp(pData+5,"01",2)<0 || DmStrncmp(pData+5,"52",2)>0))
    770                   return FALSE;
    771                else
    772                   return TRUE;
    773             default:
    774                return FALSE;
    775          }
    776       }
    777    }
    778 
    779    return FALSE;
    780 
    781 #endif
    782 }
    783 
    784 
    785 BOOLEAN
    786 DMMetaDataManager::IsTime(const DMBuffer & oData)
    787 {
    788 #ifdef DM_NO_REGEX
    789     return ::XPL_RG_Comp( XPL_RG_PATTERN_IS_TIME, (CPCHAR)oData.getBuffer() )
    790               ? SYNCML_DM_SUCCESS
    791               : SYNCML_DM_UNSUPPORTED_MEDIATYPE_FORMAT;
    792 #else
    793 
    794    for (UINT8 i=0; i<sizeof(m_pTimePattern)/sizeof(int); i++)
    795    {
    796       if (VerifyRegExp(m_pTimePattern[i], (CPCHAR)oData.getBuffer()) == SYNCML_DM_SUCCESS)
    797       {
    798          CPCHAR pData = (CPCHAR)oData.getBuffer();
    799          // Validate hour
    800          if ((DmStrncmp(pData,"00",2)<0 || DmStrncmp(pData,"23",2)>0))
    801              return FALSE;
    802 
    803          switch (i)
    804          {
    805             case 0:  // hh:mm:ss
    806             case 5:  // hh:mm:ssZ
    807                if ((DmStrncmp(pData+3,"00",2)<0 || DmStrncmp(pData+3,"59",2)>0) ||
    808                    (DmStrncmp(pData+6,"00",2)<0 || DmStrncmp(pData+6,"59",2)>0))
    809                   return FALSE;
    810                else
    811                   return TRUE;
    812             case 1:  // hh:mm
    813                if ((DmStrncmp(pData+3,"00",2)<0 || DmStrncmp(pData+3,"59",2)>0))
    814                   return FALSE;
    815                else
    816                   return TRUE;
    817             case 2:  // hhmmss
    818                if ((DmStrncmp(pData+2,"00",2)<0 || DmStrncmp(pData+2,"59",2)>0)||
    819                    (DmStrncmp(pData+4,"00",2)<0 || DmStrncmp(pData+4,"59",2)>0))
    820                   return FALSE;
    821                else
    822                   return TRUE;
    823             case 3:  // hhmm
    824                if ((DmStrncmp(pData+2,"00",2)<0 || DmStrncmp(pData+2,"59",2)>0))
    825                   return FALSE;
    826                else
    827                   return TRUE;
    828             case 4:  // hh
    829                   return TRUE;
    830             case 6:  // hh:mm:sshh:mm
    831                if ((DmStrncmp(pData,"00",2)<0 || DmStrncmp(pData,"23",2)>0)||
    832                    (DmStrncmp(pData+3,"00",2)<0 || DmStrncmp(pData+3,"59",2)>0)||
    833                    (DmStrncmp(pData+6,"00",2)<0 || DmStrncmp(pData+6,"59",2)>0)||
    834                    (DmStrncmp(pData+9,"00",2)<0 || DmStrncmp(pData+9,"23",2)>0)||
    835                    (DmStrncmp(pData+12,"00",2)<0 || DmStrncmp(pData+12,"59",2)>0))
    836                   return FALSE;
    837                else
    838                   return TRUE;
    839             default:
    840                return FALSE;
    841          }
    842       }
    843    }
    844 
    845    return FALSE;
    846 
    847 #endif
    848 }
    849 
    850 BOOLEAN
    851 DMMetaDataManager::VerifynValues(DMConstraints *pConstraints, const DMString & oNodeName)
    852 {
    853 
    854     if ( pConstraints->m_psnValues == NULL )
    855         return TRUE;
    856 
    857     DMToken oValues(TRUE,pConstraints->m_psnValues,SYNCML_DM_COMMA);
    858     CPCHAR sName = NULL;
    859 
    860     while ( (sName = oValues.nextSegment()) != NULL )
    861         if( oNodeName == sName )
    862             return TRUE;
    863     return FALSE;
    864 }
    865 
    866 
    867 BOOLEAN
    868 DMMetaDataManager::VerifyValues(DMConstraints *pConstraints, SYNCML_DM_FORMAT_T format, const DMBuffer & oData)
    869 {
    870     CPCHAR sValue = NULL;
    871 
    872     if (pConstraints->m_psValues == NULL)
    873        return TRUE;
    874 
    875     DMToken oValues(TRUE,pConstraints->m_psValues,SYNCML_DM_COMMA);
    876     sValue = oValues.nextSegment();
    877 
    878     while ( sValue )
    879     {
    880         switch(format)
    881         {
    882             case SYNCML_DM_FORMAT_INT:
    883                 if(DmAtoi((CPCHAR)oData.getBuffer()) == DmAtoi(sValue))
    884                     return TRUE;
    885                 break;
    886 
    887             case SYNCML_DM_FORMAT_CHR:
    888             case SYNCML_DM_FORMAT_FLOAT:
    889             case SYNCML_DM_FORMAT_DATE:
    890             case SYNCML_DM_FORMAT_TIME:
    891                 if( oData.compare(sValue) == TRUE )
    892                     return TRUE;
    893                 break;
    894 
    895             default:
    896                 return TRUE;
    897                 break;
    898         }
    899         sValue = oValues.nextSegment();
    900     }
    901 
    902     return FALSE;
    903 
    904 }
    905 
    906 
    907 BOOLEAN
    908 DMMetaDataManager::VerifyForeignKey(DMConstraints * pConstraints, const DMBuffer & oData)
    909 {
    910     if (pConstraints->m_psForeignKey == NULL)
    911         return TRUE;
    912 
    913     DMGetData getData;
    914     DMString strURI = pConstraints->m_psForeignKey;
    915     DMString strName( (const char*)oData.getBuffer(), oData.getSize() );
    916 
    917     strURI += "/";
    918     strURI += strName;
    919 
    920     /* Retrieve the child node names from the DM Tree.*/
    921 
    922     if( SYNCML_DM_SUCCESS != m_pTree->Get(strURI,getData,SYNCML_DM_REQUEST_TYPE_INTERNAL) )
    923         return FALSE;
    924 
    925   return TRUE;
    926 }
    927 
    928 
    929 SYNCML_DM_RET_STATUS_T
    930 DMMetaDataManager::VerifyRegExp(CPCHAR sPattern, CPCHAR sData)
    931 {
    932     BOOLEAN reg_status = FALSE;
    933 
    934 #ifndef DM_NO_REGEX
    935     reg_status = XPL_RG_Comp(sPattern, sData);
    936 #endif
    937     if ( reg_status )
    938         return SYNCML_DM_SUCCESS;
    939     else
    940         return SYNCML_DM_UNSUPPORTED_MEDIATYPE_FORMAT;
    941 }
    942 
    943 #ifndef DM_STATIC_FILES
    944 SYNCML_DM_RET_STATUS_T
    945 DMMetaDataManager::LoadBuffer(CPCHAR pPath)
    946 {
    947     DMFileHandler *fp;
    948 
    949     fp = new DMFileHandler(pPath,FALSE);
    950     if ( fp == NULL )
    951         return SYNCML_DM_FAIL;
    952 
    953     if(fp->open(XPL_FS_FILE_READ) != SYNCML_DM_SUCCESS)
    954     {
    955        DMFileHandler::operator delete (fp);
    956        return SYNCML_DM_IO_FAILURE;
    957     }
    958 
    959     UINT8 * pBuffer = fp->mmap();
    960     if ( !pBuffer )
    961     {
    962       DMFileHandler::operator delete (fp);
    963       return SYNCML_DM_FAIL;
    964     }
    965 
    966     if ( pBuffer[0] == '[' && (pBuffer[1] == '/' || pBuffer[1] == '.') )
    967     {
    968        XPL_LOG_DM_TMN_Error(("BMDF: file %s not recognized as a bmdf file, ignored\n", pPath));
    969        DMFileHandler::operator delete (fp);
    970        return SYNCML_DM_IO_FAILURE;
    971     }
    972 #ifndef DM_IGNORE_BMDF_VERIFICATION
    973     {
    974       // verify file length
    975       DMMetaDataBuffer  buf( pBuffer );
    976       UINT32 nFileSize = buf.ReadUINT32();
    977       int nVersion = buf.ReadUINT16();
    978 
    979       if ( nFileSize!= fp->size() )
    980       {
    981         XPL_LOG_DM_TMN_Error(("BMDF: file %s size %d mismatch with buffer value %d, ignored\n",pPath,fp->size(),nFileSize));
    982         DMFileHandler::operator delete (fp);
    983         return SYNCML_DM_IO_FAILURE;
    984       }
    985       if ( nVersion != CurrentBMDFVersion )
    986       {
    987         XPL_LOG_DM_TMN_Error(("BMDF: file %s supported version %d mismatch with buffer value %d, ignored\n",
    988                               pPath, (int)CurrentBMDFVersion, nVersion));
    989         DMFileHandler::operator delete (fp);
    990         return SYNCML_DM_IO_FAILURE;
    991       }
    992     }
    993 #endif
    994 
    995     fp->close();
    996     XPL_LOG_DM_TMN_Debug(("LOAD BUFFER %s\n",pPath));
    997     m_oDDFInfo.push_back((UINT32)fp);
    998     return SYNCML_DM_SUCCESS;
    999 }
   1000 #else
   1001 SYNCML_DM_RET_STATUS_T
   1002 DMMetaDataManager::LoadBuffer(UINT32 index)
   1003 {
   1004     UINT8 * pBuffer;
   1005     UINT32 size;
   1006 
   1007     pBuffer = (UINT8*)XPL_DM_GetMDF(index,&size);
   1008 
   1009     if ( !pBuffer )
   1010       return SYNCML_DM_FAIL;
   1011     m_oDDFInfo.push_back((UINT32)pBuffer);
   1012     return SYNCML_DM_SUCCESS;
   1013 }
   1014 #endif
   1015 
   1016 UINT32
   1017 DMMetaDataManager::FindNodeInChildrenList(DMMetaDataBuffer oBuffer, CPCHAR psName) const
   1018 {
   1019 
   1020     DMMetaDataNode oNode;
   1021     DMMetaDataNode oChildrenNode;
   1022     UINT32 offsetChildren = 0;
   1023 
   1024     oNode.Read(oBuffer,FALSE);
   1025     if ( oNode.IsHasMultiNodes() == FALSE )
   1026     {
   1027         for (int i=0; i<oNode.m_nNumChildren; i++)
   1028         {
   1029             oNode.SetChildrenOffset(&oBuffer,i);
   1030             offsetChildren = oBuffer.GetOffset();
   1031             oChildrenNode.ReadName(oBuffer);
   1032             if ( !DmStrcmp(oChildrenNode.m_psName,psName) )
   1033                return offsetChildren;
   1034         }
   1035     }
   1036     else
   1037     {
   1038         oNode.SetChildrenOffset(&oBuffer,0);
   1039         return oBuffer.GetOffset();
   1040     }
   1041     return 0;
   1042 }
   1043 
   1044 
   1045 CPCHAR
   1046 DMMetaDataManager::BuildSearchURI(CPCHAR szURI,
   1047                                                           DMMetaDataBuffer & oBuffer,
   1048                                                           SYNCML_DM_ACCESS_TYPE_T & accessType,
   1049                                                           DMMetaDataNode & oNode )
   1050 {
   1051 
   1052     DMParser sURIParser(szURI);
   1053     CPCHAR sSegment1 = NULL;
   1054     CPCHAR sSegment2 = NULL;
   1055 
   1056     UINT16 count1 = sURIParser.getSegmentsCount();
   1057     UINT16 count2 = m_oLastNodeLocator.m_oLocator.size();
   1058     UINT16 count = ( count1 > count2 ) ? count2 : count1;
   1059     UINT32 offset = 0;
   1060 
   1061 
   1062     for (int i=0 ; i<count; i++)
   1063     {
   1064         sSegment1 = (m_oLastNodeLocator.m_oLocator[i]).m_szName;
   1065         sSegment2 = sURIParser.nextSegment();
   1066 
   1067         if (sSegment2 != NULL && DmStrcmp(sSegment1,sSegment2) != 0 )
   1068         {
   1069             if ( i == 0 )
   1070                 return szURI;
   1071 
   1072             m_oLastNodeLocator.m_oLocator.set_size(i);
   1073             oBuffer.SetBuffer(m_oLastNodeLocator.m_pBuffer);
   1074             offset = (m_oLastNodeLocator.m_oLocator[i-1]).m_nOffset;
   1075             accessType = (m_oLastNodeLocator.m_oLocator[i-1]).m_wAccessType;
   1076             oNode.SetPath((m_oLastNodeLocator.m_oLocator[i-1]).m_strPath);
   1077             oBuffer.SetOffset(offset);
   1078             return sSegment2;
   1079         }
   1080     }
   1081 
   1082     oBuffer.SetBuffer(m_oLastNodeLocator.m_pBuffer);
   1083     if ( count2 >= count1 )
   1084     {
   1085         offset = (m_oLastNodeLocator.m_oLocator[count1-1]).m_nOffset;
   1086         accessType = (m_oLastNodeLocator.m_oLocator[count1-1]).m_wAccessType;
   1087         oNode.SetPath((m_oLastNodeLocator.m_oLocator[count1-1]).m_strPath);
   1088         oBuffer.SetOffset(offset);
   1089         return NULL;
   1090     }
   1091     else
   1092     {
   1093         offset = (m_oLastNodeLocator.m_oLocator[count2-1]).m_nOffset;
   1094         accessType = (m_oLastNodeLocator.m_oLocator[count2-1]).m_wAccessType;
   1095         oNode.SetPath((m_oLastNodeLocator.m_oLocator[count2-1]).m_strPath);
   1096 
   1097         oBuffer.SetOffset(offset);
   1098         return sURIParser.nextSegment();
   1099     }
   1100 
   1101 }
   1102 
   1103 
   1104 SYNCML_DM_RET_STATUS_T
   1105 DMMetaDataManager::SearchNode(CPCHAR szURI,
   1106                               DMMetaDataBuffer oBuffer,
   1107                               SYNCML_DM_ACCESS_TYPE_T parentAccessType,
   1108                               BOOLEAN bCheckMultiNode,
   1109                               DMMetaDataNode & oNode,
   1110                               DMMetaPCharVector* pChildDependNodes )
   1111 {
   1112 
   1113      SYNCML_DM_RET_STATUS_T ret_status = SYNCML_DM_SUCCESS;
   1114      CPCHAR sSegment = NULL;
   1115      UINT32 nodeOffset = 0;
   1116      DMURI oURI(FALSE,szURI);
   1117      BOOLEAN bIsFound = FALSE;
   1118      DMConstraints * pConstraints = NULL;
   1119 
   1120 
   1121      sSegment = oURI.nextSegment();
   1122      while( sSegment != NULL )
   1123      {
   1124         nodeOffset = FindNodeInChildrenList(oBuffer,sSegment);
   1125         if ( nodeOffset == 0 )
   1126         {
   1127             oNode.Init();
   1128             break;
   1129         }
   1130 
   1131 
   1132         oBuffer.SetOffset(nodeOffset);
   1133         oNode.Read(oBuffer,TRUE);
   1134 
   1135 
   1136         pConstraints = oNode.GetConstraints();
   1137         if ( pConstraints && pConstraints->m_psRecurAfterSegment )
   1138         {
   1139             bIsFound = TRUE;
   1140             ret_status = RemoveRecursiveSegments((char*)oURI.getTailSegments(),oNode);
   1141             if ( ret_status == SYNCML_DM_FAIL )
   1142             {
   1143                 oNode.Init();
   1144                 return ret_status;
   1145             }
   1146         }
   1147 
   1148         if ( pChildDependNodes && pConstraints )
   1149         {
   1150           if ( pConstraints->m_psChild )
   1151             pChildDependNodes->push_back( pConstraints->m_psChild );
   1152 
   1153           if ( pConstraints->m_psDepend )
   1154             pChildDependNodes->push_back( pConstraints->m_psDepend );
   1155         }
   1156 
   1157         if ( oNode.m_wAccessType == 0 )
   1158           oNode.SetAccessType(parentAccessType);
   1159 
   1160         parentAccessType = oNode.m_wAccessType;
   1161 
   1162         if ( !bIsFound )
   1163         {
   1164             oNode.AppendSegment();
   1165             m_oLastNodeLocator.m_oLocator.push_back(DMMetaNodeLocator(oNode.m_psName,
   1166                                                                                                      nodeOffset,
   1167                                                                                                      oNode.m_wAccessType,
   1168                                                                                                      oNode.GetPath()));
   1169         }
   1170 
   1171         sSegment = oURI.nextSegment();
   1172         if( sSegment == NULL )
   1173         {
   1174             if (  bCheckMultiNode )
   1175                 oNode.GetMaxMultiNodeChildren(oBuffer);
   1176             return SYNCML_DM_SUCCESS;
   1177         }
   1178 
   1179      }
   1180 
   1181      return SYNCML_DM_NOT_FOUND;
   1182 
   1183 }
   1184 
   1185 
   1186 SYNCML_DM_RET_STATUS_T
   1187 DMMetaDataManager::GetRootNode(DMMetaDataNode & oNode)
   1188 {
   1189         DMMetaDataBuffer oBuffer;
   1190 
   1191    #ifndef DM_STATIC_FILES
   1192         DMFileHandler * pFile = (DMFileHandler*)m_oDDFInfo[0];
   1193         oBuffer.SetBuffer((MDF_BUFFER_T)pFile->mmap());
   1194 #else
   1195         oBuffer.SetBuffer((MDF_BUFFER_T)m_oDDFInfo[0]);
   1196 #endif
   1197         oBuffer.SetOffset(BMDFHeaderSize); // file size and version
   1198         oNode.Read(oBuffer,TRUE);
   1199 
   1200         return SYNCML_DM_SUCCESS;
   1201 }
   1202 
   1203 
   1204 CPCHAR
   1205 DMMetaDataManager::GetStartPos(CPCHAR szURI)
   1206 {
   1207     switch ( szURI[0] )
   1208      {
   1209         case SYNCML_DM_DOT:
   1210             if (DmStrlen(szURI) >= 3)
   1211                 return &szURI[2];
   1212             break;
   1213 
   1214         case SYNCML_DM_FORWARD_SLASH:
   1215             return NULL;
   1216 
   1217         default:
   1218             return szURI;
   1219     }
   1220     return NULL;
   1221 }
   1222 
   1223 
   1224 SYNCML_DM_RET_STATUS_T
   1225 DMMetaDataManager::FindCacheNode(CPCHAR szURI,
   1226                                                     BOOLEAN bCheckMultiNode,
   1227                                                     DMMetaDataNode & oNode,
   1228                                                     DMMetaDataBuffer & oBuffer,
   1229                                                     DMMetaPCharVector* pChildDependNodes)
   1230 {
   1231     SYNCML_DM_RET_STATUS_T ret_status = SYNCML_DM_SUCCESS;
   1232     SYNCML_DM_ACCESS_TYPE_T parentAccessType;
   1233     CPCHAR sStartPos = NULL;
   1234 
   1235     if ( m_oLastNodeLocator.m_oLocator.size() == 0)
   1236         return SYNCML_DM_NOT_FOUND;
   1237 
   1238     sStartPos = BuildSearchURI((CPCHAR)szURI,oBuffer,parentAccessType, oNode);
   1239     if ( oBuffer.GetBuffer() == NULL )
   1240        return SYNCML_DM_NOT_FOUND;
   1241 
   1242     if ( sStartPos == NULL )
   1243     {
   1244         ret_status = oNode.Read(oBuffer,TRUE);
   1245         if ( ret_status == SYNCML_DM_SUCCESS && bCheckMultiNode )
   1246             ret_status = oNode.GetMaxMultiNodeChildren(oBuffer);
   1247 
   1248         if ( ret_status != SYNCML_DM_SUCCESS )
   1249             oNode.Init();
   1250         else
   1251         {
   1252             if ( oNode.m_wAccessType == 0 )
   1253                 oNode.m_wAccessType = parentAccessType;
   1254         }
   1255         return ret_status;
   1256     }
   1257     ret_status = SearchNode(sStartPos,oBuffer,parentAccessType,bCheckMultiNode,oNode, pChildDependNodes);
   1258     if ( ret_status == SYNCML_DM_SUCCESS )
   1259         return ret_status;
   1260 
   1261     return SYNCML_DM_NOT_FOUND;
   1262 
   1263 }
   1264 
   1265 
   1266 SYNCML_DM_RET_STATUS_T
   1267 DMMetaDataManager::GetNode(CPCHAR szURI,
   1268                                            BOOLEAN bCheckMultiNode,
   1269                                            DMMetaDataNode & oNode,
   1270                                            DMMetaPCharVector* pChildDependNodes /*=NULL*/)
   1271 {
   1272 
   1273      SYNCML_DM_RET_STATUS_T ret_status = SYNCML_DM_SUCCESS;
   1274      DMString sNodeURI;
   1275 
   1276      ret_status = oNode.AllocatePath(DmStrlen(szURI)+1);
   1277      if ( ret_status != SYNCML_DM_SUCCESS )
   1278            return ret_status;
   1279 
   1280      oNode.Init();
   1281 
   1282      if(m_bIsLoad == FALSE)
   1283      {
   1284         ret_status = Load();
   1285         if ( ret_status != SYNCML_DM_SUCCESS )
   1286              return ret_status;
   1287      }
   1288 
   1289      if ( DmStrcmp(szURI,".") == 0 )
   1290          return GetRootNode(oNode);
   1291 
   1292     sNodeURI = GetStartPos(szURI);
   1293     if ( sNodeURI == NULL )
   1294         return SYNCML_DM_FAIL;
   1295 
   1296     DMMetaDataBuffer oBuffer;
   1297     ret_status = FindCacheNode((CPCHAR)sNodeURI,bCheckMultiNode,oNode,oBuffer,pChildDependNodes);
   1298     if ( ret_status == SYNCML_DM_SUCCESS )
   1299         return ret_status;
   1300 
   1301     SYNCML_DM_ACCESS_TYPE_T parentAccessType;
   1302     MDF_BUFFER_T pSearchedBuffer = oBuffer.GetBuffer();
   1303     UINT32 size = m_oDDFInfo.size();
   1304 
   1305     for (UINT32 i=0; i<size; i++) // loop through all mdf's files
   1306     {
   1307 #ifndef DM_STATIC_FILES
   1308         DMFileHandler * pFile = (DMFileHandler*)m_oDDFInfo[i];
   1309         oBuffer.SetBuffer((MDF_BUFFER_T)pFile->mmap());
   1310 #else
   1311         oBuffer.SetBuffer((MDF_BUFFER_T)m_oDDFInfo[i]);
   1312 #endif
   1313         oBuffer.SetOffset(BMDFHeaderSize); // file size and version
   1314 #ifndef DM_IGNORE_BMDF_VERIFICATION
   1315         oBuffer.ResetCorrupted();
   1316 #endif
   1317         if (pSearchedBuffer == oBuffer.GetBuffer())
   1318             continue;
   1319 
   1320         oNode.Read(oBuffer,FALSE);
   1321         if (DmStrcmp(oNode.m_psName,".") != 0)
   1322         {
   1323 #ifndef DM_IGNORE_BMDF_VERIFICATION
   1324             if ( oBuffer.IsCorrupted() ){
   1325 #ifndef DM_STATIC_FILES
   1326               XPL_LOG_DM_TMN_Error(("BMDF: File %s is corrupted!\n", pFile->getFullPath()));
   1327               delete pFile;
   1328               pFile = NULL;
   1329 #endif
   1330               m_oLastNodeLocator.Init();
   1331               m_oDDFInfo.remove( i );
   1332               i--; size--;
   1333             }
   1334 #else
   1335             continue;
   1336 #endif
   1337         }
   1338         parentAccessType = oNode.m_wAccessType;
   1339         m_oLastNodeLocator.Init();
   1340         m_oLastNodeLocator.m_pBuffer = oBuffer.GetBuffer();
   1341         ret_status = SearchNode((CPCHAR)sNodeURI,oBuffer,parentAccessType,bCheckMultiNode,oNode, pChildDependNodes);
   1342 
   1343 #ifndef DM_IGNORE_BMDF_VERIFICATION
   1344         if ( oBuffer.IsCorrupted() )
   1345         {
   1346 #ifndef DM_STATIC_FILES
   1347            if (pFile != NULL)
   1348            {
   1349               XPL_LOG_DM_TMN_Error(("BMDF: File %s is corrupted!\n", pFile->getFullPath()));
   1350               delete pFile;
   1351               pFile = NULL;
   1352            }
   1353            else
   1354            {
   1355               XPL_LOG_DM_TMN_Error(("BMDF: File is corrupted!\n"));
   1356            }
   1357 #endif
   1358           m_oLastNodeLocator.Init();
   1359           m_oDDFInfo.remove( i );
   1360           i--; size--;
   1361         }
   1362 #endif
   1363 
   1364 
   1365         if ( ret_status != SYNCML_DM_NOT_FOUND )
   1366              return ret_status;
   1367 
   1368     }
   1369 
   1370     return SYNCML_DM_NOT_FOUND;
   1371 
   1372 }
   1373 
   1374 BOOLEAN
   1375 DMMetaDataManager::CheckFieldInUse(DMNode* pNode,
   1376                                                      PDmtNode pPluginNode,
   1377                                                      CPCHAR szNodeName,
   1378                                                      CPCHAR szOrigName)
   1379 {
   1380     if (pPluginNode != NULL)
   1381     {
   1382         SYNCML_DM_RET_STATUS_T e;
   1383         DmtData data;
   1384 
   1385         e = pPluginNode->GetValue(data);
   1386         if ( (e==SYNCML_DM_SUCCESS) && (data.GetType() == SYNCML_DM_DATAFORMAT_STRING) )
   1387         {
   1388             const DMString & strVal = data.GetStringValue();
   1389             if (DmStrncmp((CPCHAR)strVal.c_str(), szNodeName, DmStrlen(szNodeName)) == 0 )
   1390                return FALSE;
   1391         }
   1392         else
   1393             return FALSE;
   1394     }
   1395     else
   1396         if ( pNode->getData() && pNode->getData()->getSize() )
   1397         {
   1398             if (DmStrncmp((CPCHAR)pNode->getData()->getBuffer(), szNodeName, pNode->getData()->getSize())==0)
   1399                 return FALSE;
   1400         }
   1401     return TRUE;
   1402 }
   1403 
   1404 
   1405 BOOLEAN
   1406 DMMetaDataManager::ClearNodeValue(DMNode* pNode,
   1407                                                     PDmtNode pPluginNode,
   1408                                                     CPCHAR szNodeName,
   1409                                                     CPCHAR szOrigName)
   1410 {
   1411     if ( pPluginNode != NULL )
   1412     {
   1413         SYNCML_DM_RET_STATUS_T dm_stat;
   1414         DmtData data;
   1415 
   1416         dm_stat = pPluginNode->GetValue(data);
   1417         if ( dm_stat != SYNCML_DM_SUCCESS )
   1418             return FALSE;
   1419         if ( data.GetType() == SYNCML_DM_DATAFORMAT_STRING )
   1420         {
   1421             dm_stat = pPluginNode->SetValue(DmtData((CPCHAR)""));
   1422             if (dm_stat != SYNCML_DM_SUCCESS )
   1423                 return FALSE;
   1424         }
   1425         else
   1426             return FALSE;
   1427     }
   1428     else
   1429         if( pNode->getData() && pNode->getData()->getSize() )
   1430         {
   1431             if (DmStrncmp((CPCHAR)pNode->getData()->getBuffer(), szNodeName, pNode->getData()->getSize())==0)
   1432                 pNode->getData()->clear();
   1433         }
   1434     return TRUE;
   1435 }
   1436 
   1437 
   1438 BOOLEAN
   1439 DMMetaDataManager::ResetNodeValue(DMNode* pNode,
   1440                                                      PDmtNode pPluginNode,
   1441                                                      CPCHAR szNodeName,
   1442                                                      CPCHAR szOrigName)
   1443 {
   1444     if (pPluginNode != NULL)
   1445     {
   1446         SYNCML_DM_RET_STATUS_T dm_stat;
   1447         DmtData data;
   1448 
   1449         dm_stat = pPluginNode->GetValue(data);
   1450         if ( dm_stat != SYNCML_DM_SUCCESS )
   1451             return FALSE;
   1452 
   1453         if ( data.GetType() == SYNCML_DM_DATAFORMAT_STRING )
   1454         {
   1455             // Get Data
   1456             const DMString & strVal = data.GetStringValue();
   1457             if (DmStrncmp( (CPCHAR)strVal.c_str(), szOrigName, DmStrlen(szOrigName)) == 0)
   1458             {
   1459                     dm_stat = pPluginNode->SetValue(DmtData(szNodeName));
   1460                     if (dm_stat != SYNCML_DM_SUCCESS )
   1461                         return FALSE;
   1462             }
   1463 
   1464         }
   1465         else
   1466             return FALSE;
   1467     }
   1468     else
   1469     {
   1470         if( !pNode->getData() || !pNode->getData()->getSize() )
   1471             return TRUE;
   1472 
   1473         if (DmStrncmp((CPCHAR)pNode->getData()->getBuffer(),szOrigName,pNode->getData()->getSize()) ==0)
   1474         {
   1475             if ( pNode->getData()->assign(szNodeName) == NULL )
   1476                 return FALSE;
   1477         }
   1478     }
   1479     return TRUE;
   1480 }
   1481 
   1482 
   1483 BOOLEAN
   1484 DMMetaDataManager::VerifyOneURIDependency(DMNode* pNode,
   1485                                                                  char * sAbsoluteURI,
   1486                                                                  CPCHAR szNodeName,
   1487                                                                  CPCHAR szOneURIDep,
   1488                                                                  CPCHAR szOrigName,
   1489                                                                  SYNCML_DM_MDF_CBACK callBack,
   1490                                                                  BOOLEAN bIsMultiNode)
   1491 {
   1492     BOOLEAN ret_status = TRUE;
   1493     DMNode *psTempNode = NULL;
   1494     DMMetaDataNode oNodeMDF;
   1495     SYNCML_DM_RET_STATUS_T dm_stat = SYNCML_DM_SUCCESS;
   1496 
   1497     psTempNode = pNode->pcFirstChild;
   1498     if( !psTempNode )
   1499         return TRUE;
   1500 
   1501     DMURI oOneURI(FALSE,szOneURIDep);
   1502     CPCHAR szSegment = oOneURI.nextSegment();
   1503 
   1504     DmStrcat(sAbsoluteURI,"/");
   1505     INT32 nLen = DmStrlen(sAbsoluteURI);
   1506     while(psTempNode != NULL)
   1507     {
   1508         sAbsoluteURI[nLen] = 0;
   1509         DmStrcat(sAbsoluteURI,psTempNode->abNodeName);
   1510 
   1511         dm_stat = GetNode(sAbsoluteURI, FALSE, oNodeMDF);
   1512         if ( dm_stat == SYNCML_DM_SUCCESS )
   1513         {
   1514           if ( bIsMultiNode || psTempNode->abNodeName == szSegment )
   1515           {
   1516               if(oOneURI.getTailSegments() == NULL)
   1517                    ret_status = callBack(psTempNode, NULL,szNodeName, szOrigName);
   1518               else
   1519                  if ( !psTempNode->isPlugin() )
   1520                  {
   1521                       ret_status = VerifyOneURIDependency(psTempNode,
   1522                                                           sAbsoluteURI,
   1523                                                           szNodeName,
   1524                                                           oOneURI.getTailSegments(),
   1525                                                           szOrigName,
   1526                                                           callBack,
   1527                                                           oNodeMDF.IsHasMultiNodes());
   1528                  }
   1529                  else
   1530                  {
   1531                      PDmtAPIPluginTree tree;
   1532                      dm_stat = ((DMPluginRootNode*)psTempNode)->GetTree(tree);
   1533                      if ( dm_stat != SYNCML_DM_SUCCESS )
   1534                          return FALSE;
   1535 
   1536                      CPCHAR pbPluginURI = ((DMPluginRootNode*)psTempNode)->GetPluginURI(sAbsoluteURI);
   1537                      PDmtNode ptrNode;
   1538 
   1539                       dm_stat = tree->GetNode(pbPluginURI, ptrNode);
   1540                       if ( dm_stat != SYNCML_DM_SUCCESS )
   1541                             return FALSE;
   1542 
   1543                       ret_status = VerifyPluginURIDependency(psTempNode,
   1544                                                           ptrNode,
   1545                                                           sAbsoluteURI,
   1546                                                           szNodeName,
   1547                                                           oOneURI.getTailSegments(),
   1548                                                           szOrigName,
   1549                                                           callBack,
   1550                                                           oNodeMDF.IsHasMultiNodes());
   1551                  }
   1552 
   1553               if(ret_status == FALSE)
   1554                   return FALSE;
   1555 
   1556               if(bIsMultiNode == FALSE)
   1557                   return TRUE;
   1558            }
   1559         }
   1560 
   1561          psTempNode = psTempNode->pcNextSibling;
   1562 
   1563     }
   1564 
   1565    return ret_status;
   1566 
   1567 }
   1568 
   1569 
   1570 BOOLEAN
   1571 DMMetaDataManager::VerifyDependency(CPCHAR szNodeName,
   1572                                      CPCHAR szDependecies,
   1573                                      CPCHAR szOrigName,
   1574                                      SYNCML_DM_MDF_CBACK callBack)
   1575 {
   1576     BOOLEAN ret_status = TRUE;
   1577 
   1578     DMNode* pNode = NULL;
   1579     CPCHAR sSegment = NULL;
   1580     char * sAbsoluteURI = NULL;
   1581     DMToken oDependensies(TRUE,szDependecies,SYNCML_DM_COMMA);
   1582 
   1583 
   1584     if ( !oDependensies.getBuffer() )
   1585         return FALSE;
   1586 
   1587     pNode = m_pTree->GetRootNode();
   1588 
   1589     if ( pNode == NULL )
   1590         return FALSE;
   1591 
   1592     sAbsoluteURI = (char*)DmAllocMem( m_pTree->GetMaxTotalPathLength() + 1 );
   1593 
   1594     if ( sAbsoluteURI == NULL )
   1595         return FALSE;
   1596 
   1597     memset(sAbsoluteURI, 0, m_pTree->GetMaxTotalPathLength() + 1 );
   1598 
   1599     sSegment = oDependensies.nextSegment();
   1600     while ( sSegment )
   1601     {
   1602         if ( sSegment[0] == '.' && sSegment[1] == '/' )
   1603             sSegment += 2; // skip "./" part
   1604 
   1605         DmStrcpy(sAbsoluteURI,".");
   1606         ret_status = VerifyOneURIDependency(pNode,
   1607                                                   sAbsoluteURI,
   1608                                                   szNodeName,
   1609                                                   sSegment,
   1610                                                   szOrigName,
   1611                                                   callBack,
   1612                                                   FALSE);
   1613 
   1614             if( ret_status != TRUE)
   1615             {
   1616                 DmFreeMem(sAbsoluteURI);
   1617                 return FALSE;
   1618             }
   1619         sSegment = oDependensies.nextSegment();
   1620     }
   1621 
   1622     DmFreeMem(sAbsoluteURI);
   1623     return TRUE;
   1624 }
   1625 
   1626 
   1627 
   1628 SYNCML_DM_RET_STATUS_T
   1629 DMMetaDataManager::SetAutoNodeProperty(CPCHAR szURI, DMAddData & pAdd)
   1630 {
   1631     DMMetaDataNode oNode;
   1632     SYNCML_DM_RET_STATUS_T ret_status = SYNCML_DM_SUCCESS;
   1633     SYNCML_DM_FORMAT_T format;
   1634 
   1635     ret_status = GetNode(szURI, FALSE, oNode);
   1636 
   1637     if ( ret_status != SYNCML_DM_SUCCESS )
   1638         return ret_status;
   1639 
   1640     DMConstraints *pConstraints = oNode.GetConstraints();
   1641     DMString mimeType;
   1642 
   1643     oNode.GetMimeType(mimeType);
   1644 
   1645     if ( !pConstraints || !pConstraints->IsDefaultSet() )
   1646         format = ((oNode.m_nNodeFormat == SYNCML_DM_FORMAT_NODE) ?
   1647             SYNCML_DM_FORMAT_NODE : SYNCML_DM_FORMAT_NULL);
   1648     else
   1649         format = SYNCML_DM_FORMAT_INVALID;
   1650 
   1651     return pAdd.set(szURI,format,NULL,0,mimeType);
   1652 }
   1653 
   1654 
   1655 BOOLEAN DMMetaDataManager::IsLocal(CPCHAR szURI)
   1656 {
   1657 
   1658     DMMetaDataNode oNode;
   1659     SYNCML_DM_RET_STATUS_T ret_status = SYNCML_DM_SUCCESS;
   1660 
   1661     ret_status = GetNode(szURI, FALSE, oNode, NULL);
   1662     if ( ret_status == SYNCML_DM_SUCCESS )
   1663     {
   1664         return oNode.IsLocal();
   1665     }
   1666     return FALSE;
   1667 }
   1668 
   1669 
   1670 BOOLEAN DMMetaDataManager::IsLeaf(CPCHAR szURI)
   1671 {
   1672 
   1673     DMMetaDataNode oNode;
   1674     SYNCML_DM_RET_STATUS_T ret_status = SYNCML_DM_SUCCESS;
   1675 
   1676     ret_status = GetNode(szURI, FALSE, oNode, NULL);
   1677     if ( ret_status == SYNCML_DM_SUCCESS )
   1678     {
   1679         return oNode.IsLeaf();
   1680     }
   1681     return FALSE;
   1682 }
   1683 
   1684 
   1685 SYNCML_DM_RET_STATUS_T
   1686 DMMetaDataManager::GetPath(CPCHAR szURI, DMString & szMDF)
   1687 {
   1688 
   1689     DMMetaDataNode oNode;
   1690     SYNCML_DM_RET_STATUS_T ret_status = SYNCML_DM_SUCCESS;
   1691 
   1692     ret_status = GetNode(szURI, FALSE, oNode, NULL);
   1693     if ( ret_status == SYNCML_DM_SUCCESS )
   1694     {
   1695         const DMBuffer & oMDF = oNode.GetPath();
   1696         oMDF.copyTo(szMDF);
   1697     }
   1698     return ret_status;
   1699 }
   1700 
   1701 BOOLEAN
   1702 DMMetaDataManager::VerifyAccessType(CPCHAR szURI,
   1703                                                        SYNCML_DM_ACCESS_TYPE_T accessType,
   1704                                                        DMMetaPCharVector* pChildDependNodes /*=null*/)
   1705 {
   1706     DMMetaDataNode oNode;
   1707     SYNCML_DM_RET_STATUS_T ret_status = SYNCML_DM_SUCCESS;
   1708 
   1709     ret_status = GetNode(szURI, FALSE, oNode, pChildDependNodes);
   1710     if( ret_status != SYNCML_DM_SUCCESS)
   1711     {
   1712         // If meta information not available, the default access is Get and Exec
   1713         XPL_LOG_DM_TMN_Debug(("Meta Information isn't found %s\n",szURI));
   1714         oNode.SetAccessType(SYNCML_DM_GET_ACCESS_TYPE | SYNCML_DM_EXEC_ACCESS_TYPE);
   1715     }
   1716 
   1717     XPL_LOG_DM_TMN_Debug(("DMMetaDataManager::VerifyAccessType: call oNode.VerifyAccessType() %s\n",szURI));
   1718     BOOLEAN access = oNode.VerifyAccessType(accessType);
   1719     return access;
   1720 }
   1721 
   1722 
   1723 BOOLEAN
   1724 DMMetaDataManager::VerifyChildrenMultiNodesCount(CPCHAR szURI,
   1725                                                                        UINT16 count,
   1726                                                                        BOOLEAN& bOPiDataParent)
   1727 {
   1728     DMMetaDataNode oNode;
   1729     SYNCML_DM_RET_STATUS_T ret_status = SYNCML_DM_SUCCESS;
   1730 
   1731     ret_status = GetNode(szURI, TRUE, oNode);
   1732     if( ret_status != SYNCML_DM_SUCCESS)
   1733       return FALSE;
   1734 
   1735     return oNode.VerifyChildrenMultiNodesCount(count, bOPiDataParent);
   1736 }
   1737 
   1738 BOOLEAN
   1739 DMMetaDataManager::VerifyOPINode(CPCHAR szURI,
   1740                                                         CPCHAR& szID,
   1741                                                         SYNCML_DM_ACCESS_TYPE_T&  wAccessType,
   1742                                                         SYNCML_DM_FORMAT_T& nNodeFormat)
   1743 {
   1744     DMMetaDataNode oNode;
   1745     SYNCML_DM_RET_STATUS_T ret_status = SYNCML_DM_SUCCESS;
   1746 
   1747     szID = NULL;
   1748     ret_status = GetNode(szURI, FALSE, oNode);
   1749     if( ret_status != SYNCML_DM_SUCCESS)
   1750       return FALSE;
   1751 
   1752     return oNode.VerifyOPINode(szID, wAccessType, nNodeFormat);
   1753 }
   1754 
   1755 BOOLEAN DMMetaDataManager::IsOPiDataParent( CPCHAR szURI )
   1756 {
   1757     DMMetaDataNode oNode;
   1758     SYNCML_DM_RET_STATUS_T ret_status = SYNCML_DM_SUCCESS;
   1759 
   1760     ret_status = GetNode(szURI, TRUE, oNode);
   1761     if( ret_status != SYNCML_DM_SUCCESS)
   1762       return FALSE;
   1763 
   1764     return oNode.IsOPiDataParent();
   1765 }
   1766 
   1767 #ifdef LOB_SUPPORT
   1768 BOOLEAN DMMetaDataManager::IsESN( CPCHAR szURI )
   1769 {
   1770     DMMetaDataNode oNode;
   1771     SYNCML_DM_RET_STATUS_T ret_status = SYNCML_DM_SUCCESS;
   1772 
   1773     ret_status = GetNode(szURI, TRUE, oNode);
   1774     if( ret_status != SYNCML_DM_SUCCESS)
   1775         return FALSE;
   1776 
   1777     return oNode.IsESN();
   1778 }
   1779 #endif
   1780 
   1781 UINT16 DMMetaDataManager::UpdateChildrenList( CPCHAR szURI,
   1782                                                   DMString& strChildrenList )
   1783 {
   1784   UINT16 nChildrenCount = 0;
   1785   DMMetaDataNode oNode, oChildrenNode;
   1786   DMMetaDataBuffer oBuffer;
   1787 
   1788   if ( SYNCML_DM_SUCCESS != GetNode(szURI, TRUE, oNode) ||
   1789     !m_oLastNodeLocator.m_pBuffer ||
   1790     oNode.IsHasMultiNodes() )
   1791     return 0;
   1792 
   1793   oBuffer.SetBuffer( m_oLastNodeLocator.m_pBuffer  );
   1794 
   1795   for (int i=0; i<oNode.m_nNumChildren; i++)
   1796   {
   1797       oNode.SetChildrenOffset(&oBuffer,i);
   1798       oChildrenNode.Read(oBuffer, FALSE);
   1799 
   1800       if ( oChildrenNode.IsPluginNode() ) {
   1801         if ( !strChildrenList.empty() )
   1802           strChildrenList += "/";
   1803 
   1804         strChildrenList += oChildrenNode.m_psName;
   1805       }
   1806   }
   1807 
   1808   return nChildrenCount;
   1809 }
   1810 
   1811 
   1812 SYNCML_DM_RET_STATUS_T
   1813 DMMetaDataManager::RemoveRecursiveSegments(char* sTailSegment,
   1814                                             DMMetaDataNode & oNode)
   1815 {
   1816 
   1817     SYNCML_DM_RET_STATUS_T ret_status = SYNCML_DM_NOT_FOUND;
   1818     DMConstraints * pConstraints = oNode.GetConstraints();
   1819 
   1820 
   1821     if ( pConstraints == NULL ||
   1822          sTailSegment == NULL )
   1823         return ret_status;
   1824 
   1825     INT32 lenMatchSeg = DmStrlen(pConstraints->m_psRecurAfterSegment)+DmStrlen(oNode.m_psName)+1;
   1826     INT32 lenTailSeg = DmStrlen(sTailSegment);
   1827 
   1828     if ( lenMatchSeg > lenTailSeg )
   1829         return ret_status;
   1830 
   1831     DMString sMatchSegment;
   1832 
   1833     sMatchSegment = pConstraints->m_psRecurAfterSegment;
   1834     sMatchSegment += "/";
   1835     sMatchSegment += oNode.m_psName;
   1836 
   1837     DMParser oMatchSegmentParser(sMatchSegment);
   1838 
   1839     CPCHAR sSegment1 = NULL;
   1840     CPCHAR sSegment2 = NULL;
   1841     CPCHAR sRestTail = NULL;
   1842     for (int i=0; i<pConstraints->m_nMaxRecurrance; i++)
   1843     {
   1844         DMURI oTailSegmentParser(TRUE,sTailSegment);
   1845 
   1846         oMatchSegmentParser.reset();
   1847         for (UINT32 j=0; j<oMatchSegmentParser.getSegmentsCount()-1; j++)
   1848         {
   1849             sSegment1 = oMatchSegmentParser.nextSegment();
   1850             sSegment2 = oTailSegmentParser.nextSegment();
   1851             if ( sSegment2 == NULL )
   1852             {
   1853                 return SYNCML_DM_SUCCESS;
   1854             }
   1855             if ( DmStrcmp(sSegment1,"*") != 0 &&
   1856                  DmStrcmp(sSegment1,sSegment2) != 0 )
   1857             {
   1858                 return SYNCML_DM_SUCCESS;
   1859             }
   1860         }
   1861 
   1862         sSegment1 = oMatchSegmentParser.nextSegment();
   1863         sSegment2 = oTailSegmentParser.nextSegment();
   1864         if ( sSegment2 == NULL )
   1865         {
   1866             return SYNCML_DM_SUCCESS;
   1867         }
   1868         if ( !oNode.IsMultiNode() )
   1869         {
   1870             if ( DmStrcmp(sSegment1,"*") != 0 &&
   1871                  DmStrcmp(sSegment1,sSegment2) != 0 )
   1872             {
   1873                  return SYNCML_DM_SUCCESS;
   1874             }
   1875         }
   1876 
   1877 
   1878         sRestTail = oTailSegmentParser.getTailSegments();
   1879         if ( sRestTail != NULL )
   1880             memmove(sTailSegment, sRestTail, DmStrlen(sRestTail)+1);
   1881         else
   1882         {
   1883             sTailSegment[0] = SYNCML_DM_NULL;
   1884             break;
   1885         }
   1886 
   1887     }
   1888 
   1889     return SYNCML_DM_SUCCESS;
   1890 
   1891 
   1892 }
   1893 
   1894 
   1895 SYNCML_DM_RET_STATUS_T
   1896 DMMetaDataManager::Load()
   1897 {
   1898     SYNCML_DM_RET_STATUS_T ret_status;
   1899 
   1900     if( !m_pEnv ) return SYNCML_DM_FAIL;
   1901 
   1902 #ifndef DM_STATIC_FILES
   1903     DMString sRootMDF;
   1904     DMString sFullPath;
   1905 
   1906     m_pEnv->GetMainRFSFullPath(DM_ROOT_MDF_FILENAME,sRootMDF);
   1907 
   1908     ret_status = LoadBuffer(sRootMDF);
   1909 
   1910     if ( ret_status != SYNCML_DM_SUCCESS )
   1911         return ret_status;
   1912 
   1913     m_bIsLoad = TRUE;
   1914 
   1915     // load all extra mdf files...
   1916     ret_status = LoadDir(m_pEnv->GetWFSFullPath(NULL,sFullPath), false);
   1917 
   1918     if ( ret_status != SYNCML_DM_SUCCESS )
   1919         return SYNCML_DM_SUCCESS;
   1920 
   1921     for (INT32 nFS = 0; nFS < m_pEnv->GetRFSCount(); nFS++)
   1922     {
   1923         LoadDir( m_pEnv->GetRFSFullPath(nFS,NULL,sFullPath), nFS == 0); // ignore root.mdf only on first RO fs, since it's already loaded
   1924     }
   1925 #else
   1926     UINT8 count = XPL_DM_GetMDFCount();
   1927 
   1928     for (UINT8 index=0; index<count; index++)
   1929     {
   1930         ret_status = LoadBuffer(index);
   1931         if ( ret_status != SYNCML_DM_SUCCESS )
   1932             return ret_status;
   1933     }
   1934     m_bIsLoad = TRUE;
   1935 #endif
   1936 
   1937     return SYNCML_DM_SUCCESS;
   1938 }
   1939 
   1940 
   1941 #ifndef DM_STATIC_FILES
   1942 SYNCML_DM_RET_STATUS_T
   1943 DMMetaDataManager::LoadDir(CPCHAR szDirectory, BOOLEAN bIgnoreRoot)
   1944 {
   1945 
   1946     XPL_FS_RET_STATUS_T ret_status = SYNCML_DM_SUCCESS;
   1947     XPL_FS_SHANDLE_T search_handle = XPL_FS_SHANDLE_INVALID;
   1948     char file_name[XPL_FS_MAX_FILE_NAME_LENGTH];
   1949 
   1950     search_handle = XPL_FS_StartSearch(szDirectory, "bmdf", TRUE, &ret_status);
   1951     if ( ret_status != XPL_FS_RET_SUCCESS)
   1952       return SYNCML_DM_IO_FAILURE;
   1953 
   1954     // load all files with .mdf extension
   1955     while ( XPL_FS_GetSearchResult(search_handle,file_name) != XPL_FS_RET_NOT_FOUND )
   1956     {
   1957         if (( bIgnoreRoot || DmStrcmp(file_name, DM_ROOT_MDF_FILENAME) != 0) )
   1958         {
   1959             ret_status = LoadBuffer(file_name);
   1960             if ( ret_status != SYNCML_DM_SUCCESS)
   1961                 break;
   1962         }
   1963     }
   1964 
   1965     XPL_FS_EndSearch(search_handle);
   1966     return ret_status;
   1967 }
   1968 #endif
   1969 
   1970 
   1971 BOOLEAN
   1972 DMMetaDataManager::VerifyPluginURIDependency(DMNode* pNode,
   1973                                                                    PDmtNode pPluginNode,
   1974                                                                    char * sAbsoluteURI,
   1975                                                                    CPCHAR szNodeName,
   1976                                                                    CPCHAR szOneURIDep,
   1977                                                                    CPCHAR szOrigName,
   1978                                                                    SYNCML_DM_MDF_CBACK callBack,
   1979                                                                    BOOLEAN bIsMultiNode)
   1980 {
   1981     BOOLEAN ret_status = TRUE;
   1982     SYNCML_DM_RET_STATUS_T dm_stat = SYNCML_DM_SUCCESS;
   1983 
   1984     DmStrcat(sAbsoluteURI, "/");
   1985     DMVector<PDmtNode> vecNodes;
   1986 
   1987     dm_stat = pPluginNode->GetChildNodes(vecNodes);
   1988     if ( dm_stat == SYNCML_DM_SUCCESS )
   1989     {
   1990         DMMetaDataNode oNodeMDF;
   1991         DMURI oOneURI(FALSE, szOneURIDep);
   1992         CPCHAR szSegment = oOneURI.nextSegment();
   1993 
   1994         DMString nodeName;
   1995         INT32 nLen = DmStrlen(sAbsoluteURI);
   1996 
   1997 
   1998         for (INT32 i=0; i < vecNodes.size(); i++)
   1999         {
   2000             sAbsoluteURI[nLen] = 0;
   2001             dm_stat = vecNodes[i]->GetNodeName(nodeName);
   2002             if ( dm_stat != SYNCML_DM_SUCCESS )
   2003                 return FALSE;
   2004 
   2005             DmStrcat(sAbsoluteURI, nodeName.c_str());
   2006 
   2007             dm_stat = GetNode(sAbsoluteURI, FALSE, oNodeMDF);
   2008             if ( dm_stat == SYNCML_DM_SUCCESS)
   2009             {
   2010                 if ( bIsMultiNode || nodeName == szSegment)
   2011                 {
   2012                     if (oOneURI.getTailSegments() == NULL)
   2013                     {
   2014                         ret_status = callBack(pNode, vecNodes[i], szNodeName, szOrigName);
   2015                     }
   2016                     else
   2017                     {
   2018                         ret_status = VerifyPluginURIDependency(pNode,
   2019                                                                               vecNodes[i],
   2020                                                                               sAbsoluteURI,
   2021                                                                               szNodeName,
   2022                                                                               oOneURI.getTailSegments(),
   2023                                                                               szOrigName,
   2024                                                                               callBack,
   2025                                                                              oNodeMDF.IsHasMultiNodes());
   2026                     }
   2027 
   2028                     if (ret_status == FALSE)
   2029                         return FALSE;
   2030                     if (bIsMultiNode == FALSE)
   2031                         return TRUE;
   2032                 }
   2033             }
   2034         }
   2035     }
   2036     return ret_status;
   2037 }
   2038