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 Name: dmtNode.cc 20 21 General Description: Implementation of the DmtTreeImpl class 22 23==================================================================================================*/ 24 25#include "dmt.hpp" 26#include "dmtTreeImpl.hpp" 27#include "dmtNodeImpl.hpp" 28#include "dm_tree_util.h" 29#include "dm_tree_plugin_util.H" 30#include "dmLockingHelper.h" 31 32DmtNodeImpl::~DmtNodeImpl() 33{ 34} 35#ifdef LOB_SUPPORT 36DmtNodeImpl::DmtNodeImpl( BOOLEAN bLeaf,BOOLEAN bESN, DmtTree *ptrTree, CPCHAR oPath, CPCHAR strName ) 37{ 38 m_bLeaf = bLeaf; 39 m_ptrTree = ptrTree; 40 m_oPath = DmtGetSafeStrPtr( oPath ); 41 m_strName = strName; 42 m_bESN = bESN; 43 m_chunkOffset = 0L; // offset 44 chunkData = NULL; 45} 46#else 47DmtNodeImpl::DmtNodeImpl( BOOLEAN bLeaf, DmtTree *ptrTree, CPCHAR oPath, CPCHAR strName ) 48{ 49 m_bLeaf = bLeaf; 50 m_ptrTree = ptrTree; 51 m_oPath = DmtGetSafeStrPtr( oPath ); 52 m_strName = strName; 53} 54#endif 55SYNCML_DM_RET_STATUS_T DmtNodeImpl::GetTree( PDmtTree& ptrTree ) const 56{ 57 ptrTree = m_ptrTree; 58 return SYNCML_DM_SUCCESS; 59} 60 61 62SYNCML_DM_RET_STATUS_T DmtNodeImpl::GetPath(DMString & path) const 63{ 64 path = m_oPath; 65 if ( m_oPath != NULL && path == NULL ) 66 return SYNCML_DM_DEVICE_FULL; 67 return SYNCML_DM_SUCCESS; 68} 69 70 71SYNCML_DM_RET_STATUS_T DmtNodeImpl::GetNodeName(DMString & name) const 72{ 73 name = m_strName; 74 if ( m_strName != NULL && name == NULL ) 75 return SYNCML_DM_DEVICE_FULL; 76 return SYNCML_DM_SUCCESS; 77} 78 79SYNCML_DM_RET_STATUS_T DmtNodeImpl::GetAttributes( DmtAttributes& oAttr ) const 80{ 81 DMLockingHelper oLock( GetTree(), GetTree()->m_nLockType ); 82 83 if ( !oLock.IsLockedSuccessfully() ) 84 return oLock.GetError(); 85 86 return dmTreeObj.GetAttributes(m_oPath.c_str(), oAttr, SYNCML_DM_REQUEST_TYPE_API); 87 88} 89 90SYNCML_DM_RET_STATUS_T DmtNodeImpl::SetTitle( CPCHAR szTitle ) 91{ 92 if ( GetTree()->m_nLockType == SYNCML_DM_LOCK_TYPE_SHARED ) 93 return SYNCML_DM_TREE_READONLY; 94 95 DMLockingHelper oLock( GetTree(), SYNCML_DM_LOCK_TYPE_EXCLUSIVE ); 96 97 if ( !oLock.IsLockedSuccessfully() ) 98 return oLock.GetError(); 99 100 return GetTree()->SetNodeStringProp( m_oPath.c_str(), "Title", szTitle ); 101} 102 103SYNCML_DM_RET_STATUS_T DmtNodeImpl::SetAcl( const DmtAcl& oAcl ) 104{ 105 if ( GetTree()->m_nLockType == SYNCML_DM_LOCK_TYPE_SHARED ) 106 return SYNCML_DM_TREE_READONLY; 107 108 DMLockingHelper oLock( GetTree(), SYNCML_DM_LOCK_TYPE_EXCLUSIVE ); 109 110 if ( !oLock.IsLockedSuccessfully() ) 111 return oLock.GetError(); 112 113 return GetTree()->SetNodeStringProp( m_oPath.c_str(), "ACL", oAcl.toString().c_str()); 114} 115 116SYNCML_DM_RET_STATUS_T DmtNodeImpl::Rename( CPCHAR szNewName ) 117{ 118 if ( GetTree()->m_nLockType == SYNCML_DM_LOCK_TYPE_SHARED ) 119 return SYNCML_DM_TREE_READONLY; 120 121 DMLockingHelper oLock( GetTree(), SYNCML_DM_LOCK_TYPE_EXCLUSIVE ); 122 123 if ( !oLock.IsLockedSuccessfully() ) 124 return oLock.GetError(); 125 126 return GetTree()->SetNodeStringProp( m_oPath.c_str(), "Name", szNewName ); 127} 128 129SYNCML_DM_RET_STATUS_T DmtNodeImpl::GetValue( DmtData& oData ) const 130{ 131#ifdef LOB_SUPPORT 132if (m_bESN) 133 return SYNCML_DM_RESULTS_TOO_LARGE; 134#endif 135 136 DMLockingHelper oLock( GetTree(), GetTree()->m_nLockType ); 137 138 if ( !oLock.IsLockedSuccessfully() ) 139 return oLock.GetError(); 140 141 SYNCML_DM_RET_STATUS_T dm_stat = SYNCML_DM_SUCCESS; 142 DMGetData getData; 143 144 dm_stat = dmTreeObj.Get(m_oPath.c_str(),getData,SYNCML_DM_REQUEST_TYPE_API); 145 146 if ( dm_stat != SYNCML_DM_SUCCESS ) 147 return dm_stat; 148 149 if (getData.m_nFormat == SYNCML_DM_FORMAT_NODE ) 150 { 151 DMStringVector aChildren; 152 DMURI ptr(FALSE,getData.getCharData()); 153 CPCHAR pSegment = NULL; 154 155 oData = DmtData( aChildren ); // set type to "node" for case of empty parent 156 157 // we got list of nodes, divided by '/' 158 while ( (pSegment = ptr.nextSegment()) != NULL ) 159 { 160 dm_stat = oData.AddNodeValue(pSegment); 161 if ( dm_stat != SYNCML_DM_SUCCESS ) 162 return dm_stat; 163 } 164 } 165 else 166 dm_stat = dmBuildData(getData.m_nFormat, getData.m_oData, oData); 167 168 return dm_stat; 169} 170 171SYNCML_DM_RET_STATUS_T DmtNodeImpl::SetValue( const DmtData& value ) 172{ 173#ifdef LOB_SUPPORT 174if (m_bESN) 175 return SYNCML_DM_RESULTS_TOO_LARGE; 176#endif 177 178 if ( GetTree()->m_nLockType == SYNCML_DM_LOCK_TYPE_SHARED ) 179 return SYNCML_DM_TREE_READONLY; 180 181 DMLockingHelper oLock( GetTree(), SYNCML_DM_LOCK_TYPE_EXCLUSIVE ); 182 183 if ( !oLock.IsLockedSuccessfully() ) 184 return oLock.GetError(); 185 186 SYNCML_DM_RET_STATUS_T dm_stat = SYNCML_DM_SUCCESS; 187 DMAddData oReplace; 188 189 dm_stat = oReplace.set(m_oPath.c_str(),value,"text/plain"); 190 191 if ( dm_stat != SYNCML_DM_SUCCESS ) 192 return dm_stat; 193 194 return dmTreeObj.Replace(oReplace,SYNCML_DM_REQUEST_TYPE_API); 195} 196 197SYNCML_DM_RET_STATUS_T DmtNodeImpl::GetChildNodes( DMVector<PDmtNode>& oChildren ) const 198{ 199 DMStringVector aChildren; 200 return GetChildNodes( oChildren, aChildren ); 201} 202 203SYNCML_DM_RET_STATUS_T DmtNodeImpl::GetChildNodes( DMVector<PDmtNode>& oChildren, DMStringVector& aChildren ) const 204{ 205 // cache current time for last access time updates 206 DMTreeCacheCurrentTime cacheTime(&dmTreeObj); 207 208 oChildren.clear(); // remove all previous items from array 209 210 if ( m_bLeaf ) 211 return SYNCML_DM_FAIL; 212 213 DmtData oData; 214 215 SYNCML_DM_RET_STATUS_T dm_stat = GetValue( oData ); 216 217 if ( dm_stat != SYNCML_DM_SUCCESS ) 218 return dm_stat; 219 220 dm_stat = oData.GetNodeValue( aChildren ); 221 222 if ( dm_stat != SYNCML_DM_SUCCESS ) 223 return dm_stat; 224 225 for ( int i = 0; i < aChildren.size(); i++ ) 226 { 227 DMString oPath = m_oPath; 228 229 oPath += "/"; 230 oPath += aChildren[i]; 231 232 PDmtNode ptrNode; 233 234 dm_stat = GetTree()->GetNodeByFullPath( oPath.c_str(), ptrNode ); 235 if ( dm_stat != SYNCML_DM_SUCCESS ) 236 return dm_stat; 237 238 oChildren.push_back( ptrNode ); 239 } 240 241 return SYNCML_DM_SUCCESS; 242} 243 244 245 246BOOLEAN DmtNodeImpl::IsLeaf() const 247{ 248 return m_bLeaf; 249} 250 251SYNCML_DM_RET_STATUS_T DmtNodeImpl::GetChildNode( CPCHAR szPath, PDmtNode& ptrNode ) 252{ 253 DMString oPath = m_oPath; 254 255 oPath += "/"; 256 oPath += DmtGetSafeStrPtr( szPath ); 257 258 return GetTree()->GetNodeByFullPath( oPath.c_str(), ptrNode ); 259} 260 261 262SYNCML_DM_RET_STATUS_T DmtNodeImpl::Execute( CPCHAR strData, DMString& result ) 263{ 264 265 if ( GetTree()->m_nLockType == SYNCML_DM_LOCK_TYPE_SHARED ) 266 return SYNCML_DM_TREE_READONLY; 267 268 return dmTreeObj.Exec(m_oPath.c_str(),strData,result); 269} 270 271// implementation helpers 272DmtTreeImpl* DmtNodeImpl::GetTree() const 273{ 274 return (DmtTreeImpl*)m_ptrTree.GetPtr(); 275} 276#ifdef LOB_SUPPORT 277 SYNCML_DM_RET_STATUS_T DmtNodeImpl:: GetEngineChunkData(void) 278{ 279 SYNCML_DM_RET_STATUS_T retStatus = SYNCML_DM_SUCCESS; 280 DMGetData getData; 281 282 retStatus = getData.set(chunkData, m_chunkOffset); 283 284 if ( retStatus != SYNCML_DM_SUCCESS ) 285 return retStatus; 286 287 retStatus = dmTreeObj.Get(m_oPath.c_str(),getData,SYNCML_DM_REQUEST_TYPE_API); 288 289 if ( retStatus != SYNCML_DM_SUCCESS ) 290 return retStatus; 291 292 UINT32 returnLen; 293 retStatus = chunkData->GetReturnLen(returnLen); 294 m_chunkOffset += returnLen; 295 296 return retStatus; 297} 298 SYNCML_DM_RET_STATUS_T DmtNodeImpl::GetFirstChunk(DmtDataChunk& dmtChunkData) 299 { 300 DMLockingHelper oLock( GetTree(), GetTree()->m_nLockType ); 301 302 if ( !oLock.IsLockedSuccessfully() ) 303 return oLock.GetError(); 304 305 SYNCML_DM_RET_STATUS_T retStatus = SYNCML_DM_SUCCESS; 306 if (!m_bESN) 307 return SYNCML_DM_UNSUPPORTED_MEDIATYPE_FORMAT; 308 309 if( chunkData != NULL) 310 { 311 if(chunkData != &dmtChunkData) 312 { retStatus = chunkData->FreeChunkBuffer(); 313 if(retStatus!= SYNCML_DM_SUCCESS) 314 return retStatus; 315 } 316 } 317 retStatus = dmtChunkData.AllocateChunkBuffer(); 318 if(retStatus!= SYNCML_DM_SUCCESS) 319 return retStatus; 320 chunkData = &dmtChunkData; 321 m_chunkOffset = 0L; 322 323 retStatus = GetEngineChunkData(); 324 return retStatus; 325 } 326 SYNCML_DM_RET_STATUS_T DmtNodeImpl::GetNextChunk(DmtDataChunk& dmtChunkData) 327 { 328 DMLockingHelper oLock( GetTree(), GetTree()->m_nLockType ); 329 330 if ( !oLock.IsLockedSuccessfully() ) 331 return oLock.GetError(); 332 333 SYNCML_DM_RET_STATUS_T retStatus = SYNCML_DM_SUCCESS; 334 if (!m_bESN) 335 return SYNCML_DM_UNSUPPORTED_MEDIATYPE_FORMAT; 336 337 if(( chunkData == NULL) ||(chunkData != &dmtChunkData)) 338 return SYNCML_DM_INVALID_PARAMETER; 339 340 retStatus = GetEngineChunkData(); 341 return retStatus; 342 } 343 344 SYNCML_DM_RET_STATUS_T DmtNodeImpl:: SetEngineChunkData(BOOLEAN isLastChunk) 345 { 346 SYNCML_DM_RET_STATUS_T retStatus = SYNCML_DM_SUCCESS; 347 DMAddData oReplace; 348 349 retStatus = oReplace.set(m_oPath.c_str(), chunkData, m_chunkOffset, isLastChunk); 350 351 if ( retStatus != SYNCML_DM_SUCCESS ) 352 return retStatus; 353 354 retStatus = dmTreeObj.Replace(oReplace,SYNCML_DM_REQUEST_TYPE_API); 355 if ( retStatus != SYNCML_DM_SUCCESS ) 356 return retStatus; 357 358 UINT32 dataLen; 359 retStatus = chunkData->GetChunkDataSize(dataLen); 360 m_chunkOffset += dataLen; 361 return retStatus; 362 } 363 364 SYNCML_DM_RET_STATUS_T DmtNodeImpl:: SetFirstChunk(DmtDataChunk& dmtChunkData) 365 { 366 if (!m_bESN) 367 return SYNCML_DM_UNSUPPORTED_MEDIATYPE_FORMAT; 368 369 if ( GetTree()->m_nLockType == SYNCML_DM_LOCK_TYPE_SHARED ) 370 return SYNCML_DM_TREE_READONLY; 371 372 DMLockingHelper oLock( GetTree(), SYNCML_DM_LOCK_TYPE_EXCLUSIVE ); 373 374 if ( !oLock.IsLockedSuccessfully() ) 375 return oLock.GetError(); 376 377 SYNCML_DM_RET_STATUS_T retStatus = SYNCML_DM_SUCCESS; 378 if (!m_bESN) 379 return SYNCML_DM_UNSUPPORTED_MEDIATYPE_FORMAT; 380 381 382 if (chunkData != NULL) 383 { 384 if(chunkData != &dmtChunkData) 385 { retStatus = chunkData->FreeChunkBuffer(); 386 if(retStatus!= SYNCML_DM_SUCCESS) 387 return retStatus; 388 } 389 } 390 retStatus = dmtChunkData.AllocateChunkBuffer(); 391 if(retStatus!= SYNCML_DM_SUCCESS) 392 return retStatus; 393 chunkData = &dmtChunkData; 394 m_chunkOffset = 0L; 395 396 retStatus = SetEngineChunkData(FALSE); 397 return retStatus; 398 399 } 400 401 SYNCML_DM_RET_STATUS_T DmtNodeImpl::SetNextChunk(DmtDataChunk& dmtChunkData) 402 { 403 if (!m_bESN) 404 return SYNCML_DM_UNSUPPORTED_MEDIATYPE_FORMAT; 405 406 if ( GetTree()->m_nLockType == SYNCML_DM_LOCK_TYPE_SHARED ) 407 return SYNCML_DM_TREE_READONLY; 408 409 DMLockingHelper oLock( GetTree(), SYNCML_DM_LOCK_TYPE_EXCLUSIVE ); 410 411 if ( !oLock.IsLockedSuccessfully() ) 412 return oLock.GetError(); 413 SYNCML_DM_RET_STATUS_T retStatus = SYNCML_DM_SUCCESS; 414 if (!m_bESN) 415 return SYNCML_DM_UNSUPPORTED_MEDIATYPE_FORMAT; 416 if(( chunkData == NULL) ||(chunkData != &dmtChunkData)) 417 return SYNCML_DM_INVALID_PARAMETER; 418 419 retStatus = SetEngineChunkData(FALSE); 420 421 return retStatus; 422 423 } 424 SYNCML_DM_RET_STATUS_T DmtNodeImpl::SetLastChunk(DmtDataChunk& dmtChunkData) 425 { 426 if (!m_bESN) 427 return SYNCML_DM_UNSUPPORTED_MEDIATYPE_FORMAT; 428 429 if ( GetTree()->m_nLockType == SYNCML_DM_LOCK_TYPE_SHARED ) 430 return SYNCML_DM_TREE_READONLY; 431 432 DMLockingHelper oLock( GetTree(), SYNCML_DM_LOCK_TYPE_EXCLUSIVE ); 433 434 if ( !oLock.IsLockedSuccessfully() ) 435 return oLock.GetError(); 436 SYNCML_DM_RET_STATUS_T retStatus = SYNCML_DM_SUCCESS; 437 if (!m_bESN) 438 return SYNCML_DM_UNSUPPORTED_MEDIATYPE_FORMAT; 439 if(( chunkData == NULL) ||(chunkData != &dmtChunkData)) 440 return SYNCML_DM_INVALID_PARAMETER; 441 442 retStatus = SetEngineChunkData(TRUE); 443 return retStatus; 444 445} 446boolean DmtNodeImpl::IsExternalStorageNode(void) const 447{ return m_bESN; 448} 449 450#else 451SYNCML_DM_RET_STATUS_T DmtNodeImpl::GetFirstChunk(DmtDataChunk& dmtChunkData) 452{ 453 return SYNCML_DM_FEATURE_NOT_SUPPORTED; 454} 455SYNCML_DM_RET_STATUS_T DmtNodeImpl::GetNextChunk(DmtDataChunk& dmtChunkData) 456{ 457 return SYNCML_DM_FEATURE_NOT_SUPPORTED; 458} 459SYNCML_DM_RET_STATUS_T DmtNodeImpl::SetFirstChunk(DmtDataChunk& dmtChunkData) 460{ 461 return SYNCML_DM_FEATURE_NOT_SUPPORTED; 462} 463SYNCML_DM_RET_STATUS_T DmtNodeImpl::SetNextChunk(DmtDataChunk& dmtChunkData) 464{ 465 return SYNCML_DM_FEATURE_NOT_SUPPORTED; 466} 467SYNCML_DM_RET_STATUS_T DmtNodeImpl::SetLastChunk(DmtDataChunk& dmtChunkData) 468{ 469 return SYNCML_DM_FEATURE_NOT_SUPPORTED; 470} 471boolean DmtNodeImpl::IsExternalStorageNode(void) const { return FALSE;} 472 473#endif 474