messagingfw/msgsrvnstore/server/src/CMsvCachedStore.cpp
changeset 0 8e480a14352b
child 34 b66b8f3a7fd8
equal deleted inserted replaced
-1:000000000000 0:8e480a14352b
       
     1 // Copyright (c) 2001-2009 Nokia Corporation and/or its subsidiary(-ies).
       
     2 // All rights reserved.
       
     3 // This component and the accompanying materials are made available
       
     4 // under the terms of "Eclipse Public License v1.0"
       
     5 // which accompanies this distribution, and is available
       
     6 // at the URL "http://www.eclipse.org/legal/epl-v10.html".
       
     7 //
       
     8 // Initial Contributors:
       
     9 // Nokia Corporation - initial contribution.
       
    10 //
       
    11 // Contributors:
       
    12 //
       
    13 // Description:
       
    14 //
       
    15 
       
    16 #include "CMsvCachedStore.h"
       
    17 #include "MSVSTORE.H"
       
    18 #include "MSVUTILS.H"
       
    19 
       
    20 #include <mmsvstoremanager.h>
       
    21 
       
    22 const TInt KMsvFlatBufferChunkSize=0x400;
       
    23 
       
    24 
       
    25 enum TCMsvCachedStorePanic {
       
    26 	EReadingWhileCommitingStream=1,
       
    27 	EReadingWhileCommitingStore=2,
       
    28 	EReadingOrWritingWhileRevertingStore=3,
       
    29 	EReadingOrWritingWhileDeleteStream=4
       
    30 	};
       
    31 
       
    32 _LIT(KCachedStorePanic, "CMsvCachedStore");
       
    33 
       
    34 void Panic(TCMsvCachedStorePanic aPanic)
       
    35 	{
       
    36 	User::Panic(KCachedStorePanic,aPanic);
       
    37 	}
       
    38 
       
    39 
       
    40 class HMsvReadBuf : public TMemBuf
       
    41 	{
       
    42 public:
       
    43 	HMsvReadBuf(const TDesC8 &aBuf, CMsvCachedStore &aStore);
       
    44 private:
       
    45 	virtual void DoRelease();
       
    46 private:
       
    47 	CMsvCachedStore &iCachedStore;
       
    48 	};
       
    49 
       
    50 
       
    51 class HMsvWriteBuf : public TBufBuf
       
    52 	{
       
    53 public:
       
    54 	static HMsvWriteBuf* NewL(TUid aUid,CMsvCachedStore& aStore);
       
    55 private:
       
    56 	HMsvWriteBuf(TUid aUid,CMsvCachedStore& aStore);
       
    57 	virtual void DoRelease();
       
    58 	virtual void DoSynchL();
       
    59 private:
       
    60 	CBufBase*        iBuf;
       
    61 	CMsvCachedStore* iStore;
       
    62 	TUid			 iUid;
       
    63 	};
       
    64 
       
    65 
       
    66 const TUid KMsvEntryFile={0x10003C68};
       
    67 
       
    68 TPairedTUidHBufC8::TPairedTUidHBufC8() : iBuf(NULL) {}
       
    69 
       
    70 void TPairedTUidHBufC8::ExternalizeL(RWriteStream &aStream) const
       
    71 	{
       
    72 	aStream << iUid;
       
    73 	aStream << *iBuf;
       
    74 	}
       
    75 
       
    76 void TPairedTUidHBufC8::InternalizeL(RReadStream &aStream)
       
    77 	{
       
    78 	aStream >> iUid;
       
    79 	// the 0x1000000 means that it will return KErrCorrupt
       
    80 	// if the file says it contains a string of longer than 16 meg
       
    81 	iBuf=HBufC8::NewL(aStream,0x1000000);
       
    82 	}
       
    83 
       
    84 
       
    85 CMsvCachedStore* CMsvCachedStore::OpenL(TMsvId aId, MMsvStoreManager& aStoreManager, TBool aReadOnly)
       
    86 	{
       
    87 	CMsvCachedStore* me = new(ELeave) CMsvCachedStore(aId, aStoreManager);
       
    88 	CleanupStack::PushL(me);
       
    89 	me->ConstructL(aReadOnly);
       
    90 	CleanupStack::Pop(me);
       
    91 	return(me);
       
    92 	}
       
    93 
       
    94 
       
    95 CMsvCachedStore::CMsvCachedStore(TMsvId aId, MMsvStoreManager& aStoreManager)
       
    96 	: iEntryId(aId), iStoreManager(aStoreManager)
       
    97 	{
       
    98 	}
       
    99 
       
   100 void CMsvCachedStore::ConstructL(TBool aReadOnly)
       
   101 	{
       
   102 	iStreams=new(ELeave) CArrayFixFlat<TPairedTUidHBufC8>(5);
       
   103 
       
   104 	RFile storeFile;
       
   105 	TInt err = iStoreManager.OpenFileStoreForRead(iEntryId, storeFile);
       
   106 	
       
   107 	if( err != KErrNotFound )
       
   108 		{
       
   109 		if( err==KErrNone )
       
   110 			LoadL(storeFile); // the load takes ownership of the RFile
       
   111 		else
       
   112 			User::Leave(err);
       
   113 		}
       
   114 	else if(aReadOnly)
       
   115 		User::Leave(err);
       
   116 	}
       
   117 
       
   118 TInt CMsvCachedStore::Size() const
       
   119 	{
       
   120 	return iSize;
       
   121 	}
       
   122 
       
   123 void CMsvCachedStore::DeleteL()
       
   124 	{
       
   125 #if (defined SYMBIAN_MESSAGESTORE_HEADER_BODY_USING_SQLDB)
       
   126 	if(iHeaderFieldList.Count())
       
   127 		{
       
   128 		iStoreManager.DeleteHeaderEntryL(iMtmId, iEntryId);
       
   129 		}	
       
   130 #endif
       
   131 
       
   132 	iStoreManager.DeleteFileStoreL(iEntryId);
       
   133 	}
       
   134 
       
   135 
       
   136 
       
   137 #if (defined SYMBIAN_MESSAGESTORE_HEADER_BODY_USING_SQLDB)
       
   138 
       
   139 CMsvCachedStore* CMsvCachedStore::OpenL(TMsvId aId, MMsvStoreManager& aStoreManager, TBool aReadOnly,TUid aMtmId)
       
   140 	{
       
   141 	CMsvCachedStore* me = new(ELeave) CMsvCachedStore(aId, aStoreManager);
       
   142 	CleanupStack::PushL(me);
       
   143 	me->ConstructDBL(aReadOnly,aMtmId);
       
   144 	CleanupStack::Pop(me);
       
   145 	return(me);
       
   146 	}
       
   147 
       
   148 
       
   149 void CMsvCachedStore::ConstructDBL(TBool aReadOnly,TUid aMtmId)
       
   150 	{
       
   151 	iStreams=new(ELeave) CArrayFixFlat<TPairedTUidHBufC8>(5);
       
   152 
       
   153 	RFile storeFile;
       
   154 	TInt err = iStoreManager.OpenFileStoreForRead(iEntryId, storeFile);
       
   155 	
       
   156 	if(err != KErrNotFound)
       
   157 		{
       
   158 		if( err==KErrNone )
       
   159 			{
       
   160 			LoadL(storeFile); // the load takes ownership of the RFile
       
   161 			if(aReadOnly)
       
   162 				isNewEntry = EFalse;
       
   163 			else
       
   164 				isNewEntry = ETrue;
       
   165 			TRAP_IGNORE(LoadHeaderEntryL(aMtmId,aReadOnly));
       
   166 			}
       
   167 		else
       
   168 			{
       
   169 			User::Leave(err);
       
   170 			}
       
   171 		}
       
   172 	else 
       
   173 		{
       
   174 		TRAPD(err2, LoadHeaderEntryL(aMtmId,aReadOnly));
       
   175 		if (err2 == KErrNotFound)
       
   176 				{
       
   177 				User::Leave(err);
       
   178 				}
       
   179 		}
       
   180 	isDbStore=iStoreManager.DoesHeaderTableExist(aMtmId);	
       
   181 	}
       
   182 
       
   183 
       
   184 
       
   185 /**
       
   186 Assign the  header Fields in to header Field list.
       
   187 @param aHeaderFields : CHeaderFields*
       
   188 @return None.
       
   189 */
       
   190 void CMsvCachedStore::AssignL(CHeaderFields* aHeaderFields)
       
   191 	{
       
   192 	TUid uid = aHeaderFields->iUid;
       
   193 	for(TInt index=0; index<iHeaderFieldList.Count(); index++)
       
   194 		{
       
   195 		if(iHeaderFieldList[index]->iUid == uid)
       
   196 			{
       
   197 			delete iHeaderFieldList[index];
       
   198 			iHeaderFieldList[index] = aHeaderFields;
       
   199 			return;
       
   200 			}		
       
   201 		}
       
   202 	iHeaderFieldList.AppendL(aHeaderFields);
       
   203 	}
       
   204 
       
   205 /**
       
   206 Get the header Fields for respective UID.
       
   207 @param aUid : A Uid
       
   208 @param aHeaderFields : CHeaderFields*&
       
   209 
       
   210 @return None.
       
   211 */
       
   212 
       
   213 void CMsvCachedStore::GetHeaderL(TUid aUid, CHeaderFields*& aHeaderFields)
       
   214 	{
       
   215 	for(TInt index=0; index<iHeaderFieldList.Count(); index++)
       
   216 		{
       
   217 		if(iHeaderFieldList[index]->iUid == aUid)
       
   218 			{
       
   219 			aHeaderFields = iHeaderFieldList[index];
       
   220 			return;
       
   221 			}	
       
   222 		}
       
   223 	User::Leave(KErrNotFound);
       
   224 	}
       
   225 
       
   226 
       
   227 /**
       
   228 Load the Header Entry .
       
   229 @param aMtmId A Mtm TUid.
       
   230 @return None.
       
   231 @internalComponent
       
   232 */
       
   233 
       
   234 void CMsvCachedStore::LoadHeaderEntryL(const TUid aMtmId,TBool aReadOnly)
       
   235 	{
       
   236 	TRAPD (err ,iStoreManager.LoadHeaderEntryL(aMtmId, iEntryId, iHeaderFieldList));
       
   237 	if((err == KErrNotFound) && aReadOnly)
       
   238 		{
       
   239 		User::Leave(err);
       
   240 		}
       
   241 		
       
   242 	if(err == KErrNotFound)
       
   243 		{
       
   244 		isNewEntry = ETrue;
       
   245 		iSize = 0;
       
   246 		}
       
   247 	else
       
   248 		{
       
   249 		isNewEntry = EFalse;
       
   250 		if(err == KErrNone)
       
   251 			{
       
   252 			for(TInt index=0; index<iHeaderFieldList.Count(); index++)
       
   253 				{
       
   254 				for(TInt i =0 ; i < (iHeaderFieldList)[index]->iFieldPairList.Count() ;i++ )
       
   255 					{
       
   256 					if(((iHeaderFieldList)[index]->iFieldPairList[i]->iFieldTextValue) != NULL)
       
   257 						iSize += (iHeaderFieldList)[index]->iFieldPairList[i]->iFieldTextValue->Length();
       
   258 					}
       
   259 				}
       
   260 			}
       
   261 		else
       
   262 			{
       
   263 			User::Leave(err);	
       
   264 			}
       
   265 		}
       
   266 	}
       
   267 	
       
   268 #endif
       
   269 /**
       
   270 
       
   271 The CMsvCachedStore::Remove method
       
   272 
       
   273 Removes the stream from the array, ignores the fact that
       
   274 it might not exist.
       
   275 
       
   276 @internalAll
       
   277 @param				 aUid	Stream to remove
       
   278 */
       
   279 void CMsvCachedStore::Remove(TUid aUid)
       
   280 	{
       
   281 #if (defined SYMBIAN_MESSAGESTORE_HEADER_BODY_USING_SQLDB)
       
   282 	for(TInt index=0; index<iHeaderFieldList.Count(); index++)
       
   283 		{
       
   284 		if( (iHeaderFieldList)[index]->iUid == aUid )
       
   285 			{
       
   286 			iHeaderFieldList.Remove(index);
       
   287 			TRAP_IGNORE(iStoreManager.UpdateHeaderEntryL(iMtmId, iEntryId, iHeaderFieldList)); 
       
   288 			return;
       
   289 			}
       
   290 		}	
       
   291 #endif
       
   292 
       
   293 	DeleteStream(aUid);
       
   294 	}
       
   295 
       
   296 
       
   297 /**
       
   298 
       
   299 The CMsvCachedStore::RemoveL method
       
   300 
       
   301 Removes a stream from the array, leaves if the stream is not found
       
   302 
       
   303 @leave 
       
   304 @internalAll
       
   305 @param				 aUid	Stream to remove
       
   306 */
       
   307 void CMsvCachedStore::RemoveL(TUid aUid)
       
   308 	{
       
   309 	User::LeaveIfError(DeleteStream(aUid));
       
   310 	}
       
   311 
       
   312 
       
   313 /**
       
   314 
       
   315 The CMsvCachedStore::Revert method
       
   316 
       
   317 Reloads the array of streams from the store
       
   318 ignores errors that might occur.
       
   319 
       
   320 
       
   321 @internalAll
       
   322 */
       
   323 void CMsvCachedStore::Revert()
       
   324 	{
       
   325      TRAP_IGNORE(RevertL());
       
   326 	}
       
   327 
       
   328 
       
   329 /**
       
   330 
       
   331 The CMsvCachedStore::RevertL method
       
   332 
       
   333   Reloads the streams from the file
       
   334 
       
   335 @leave
       
   336 @internalAll
       
   337 */
       
   338 void CMsvCachedStore::RevertL()
       
   339 	{
       
   340 	__ASSERT_ALWAYS(iReaderCount==0 && iWriterCount==0, Panic(EReadingOrWritingWhileRevertingStore));
       
   341 	CleanArray();
       
   342 	iStreams=new(ELeave) CArrayFixFlat<TPairedTUidHBufC8>(5);
       
   343 	
       
   344 	RFile storeFile;
       
   345 	User::LeaveIfError(iStoreManager.OpenFileStoreForRead(iEntryId, storeFile));
       
   346 	LoadL(storeFile); // the load takes ownership of the RFile	
       
   347 
       
   348 	}
       
   349 
       
   350 
       
   351 /**
       
   352 
       
   353 The CMsvCachedStore::Commit method
       
   354 
       
   355   Saves the current state of the stream array to the file
       
   356 
       
   357 @return			error
       
   358 @internalAll
       
   359 */
       
   360 TInt CMsvCachedStore::Commit() 
       
   361 	{
       
   362 	TRAPD(error,CommitL());
       
   363 	return(error);
       
   364 	}
       
   365 
       
   366 
       
   367 /**
       
   368 
       
   369 The CMsvCachedStore::CommitL method
       
   370 
       
   371   Saves the current state of the stream array to the file
       
   372   leaves with if error occurs
       
   373 
       
   374 @leave
       
   375 @internalAll
       
   376 */
       
   377 void CMsvCachedStore::CommitL()
       
   378 	{
       
   379 	__ASSERT_ALWAYS(iWriterCount==0,Panic(EReadingWhileCommitingStore));
       
   380 	SaveL();
       
   381 	}
       
   382 
       
   383 
       
   384 void CMsvCachedStore::CleanArray()
       
   385 	{
       
   386 	if(iStreams!=NULL)
       
   387 		{
       
   388 		TInt count=iStreams->Count();
       
   389 		while(count--) delete iStreams->At(count).iBuf;
       
   390 		}
       
   391 	delete iStreams;
       
   392 	iStreams=NULL;
       
   393 	}
       
   394 
       
   395 /**
       
   396 
       
   397 The CMsvCachedStore::~CMsvCachedStore method
       
   398 
       
   399 @internalAll
       
   400 */
       
   401 CMsvCachedStore::~CMsvCachedStore()
       
   402 	{
       
   403 #if (defined SYMBIAN_MESSAGESTORE_HEADER_BODY_USING_SQLDB)
       
   404 	iHeaderFieldList.ResetAndDestroy();
       
   405 	iHeaderFieldList.Close();
       
   406 #endif
       
   407 	CleanArray();
       
   408 	}
       
   409 
       
   410 
       
   411 TBool CMsvCachedStore::IsNullL() const
       
   412 	{
       
   413 #if (defined SYMBIAN_MESSAGESTORE_HEADER_BODY_USING_SQLDB)
       
   414 	if(iStreams->Count()==0)
       
   415 		{
       
   416 		if(iHeaderFieldList.Count() ==0)
       
   417 			{
       
   418 			return ETrue;
       
   419 			}
       
   420 		else
       
   421 			{
       
   422 			return EFalse;
       
   423 			}
       
   424 		}
       
   425 	else
       
   426 		{
       
   427 		return EFalse;
       
   428 		}
       
   429 #else
       
   430 	return(iStreams->Count()==0);
       
   431 #endif
       
   432 	}
       
   433 
       
   434 
       
   435 /**
       
   436 
       
   437 The CMsvCachedStore::IsPresentL method
       
   438 
       
   439   checks to see if the stream is in the array
       
   440 
       
   441 @return		ETrue if it exists EFalse if not.
       
   442 @internalAll
       
   443 @param				 aUid	stream to check for
       
   444 */
       
   445 TBool CMsvCachedStore::IsPresentL(TUid aUid) const
       
   446 	{
       
   447 #if (defined SYMBIAN_MESSAGESTORE_HEADER_BODY_USING_SQLDB)
       
   448 	for(TInt index=0; index<iHeaderFieldList.Count(); index++)
       
   449 		{
       
   450 		if(iHeaderFieldList[index]->iUid == aUid)
       
   451 			{
       
   452 			return ETrue;
       
   453 			}
       
   454 		}
       
   455 #endif 	
       
   456 	TInt pos;
       
   457 	if(FindStream(aUid,pos)==KErrNone) return(ETrue);
       
   458 	else return(EFalse);
       
   459 	}
       
   460 
       
   461 
       
   462 
       
   463 /**
       
   464 
       
   465 The CMsvCachedStore::CreateOrReplaceStreamL method
       
   466 
       
   467   If a stream is present with this id it replaces the
       
   468   data in that stream with aBuf, otherwise it adds a new
       
   469   stream with the data in aBuf
       
   470 
       
   471 @internalAll
       
   472 @param				 aUid	stream id
       
   473 @param				 *aBuf	data, takes ownership
       
   474 */
       
   475 void CMsvCachedStore::CreateOrReplaceStreamL(TUid aUid, CBufBase &aBuf)
       
   476 	{
       
   477 	__ASSERT_ALWAYS(iReaderCount==0, Panic(EReadingWhileCommitingStream));
       
   478 	TInt pos;
       
   479 	HBufC8* buffer=FlattenLC(aBuf);
       
   480 	if(FindStream(aUid,pos)==KErrNone)
       
   481 		{
       
   482 		delete iStreams->At(pos).iBuf;
       
   483 		iStreams->At(pos).iBuf=buffer;
       
   484 		}
       
   485 	else
       
   486 		{
       
   487 		TPairedTUidHBufC8 entry;
       
   488 		entry.iUid=aUid;
       
   489 		entry.iBuf=buffer;
       
   490 		iStreams->InsertL(pos,entry);
       
   491 		}
       
   492 	CleanupStack::Pop(buffer);
       
   493 	}
       
   494 
       
   495 HBufC8* CMsvCachedStore::FlattenLC(CBufBase &aBuf)
       
   496 	{
       
   497 	TInt size=aBuf.Size();
       
   498 	HBufC8 *buffer=HBufC8::NewLC(size);
       
   499 	TPtr8 ptr(buffer->Des());
       
   500 
       
   501 	RDesWriteStream writer(ptr);
       
   502 	RBufReadStream reader(aBuf);
       
   503 	writer.WriteL(reader,size);
       
   504 	writer.CommitL();
       
   505 	return(buffer);
       
   506 	}
       
   507 
       
   508 
       
   509 /**
       
   510 
       
   511 The CMsvCachedStore::GetStream method
       
   512 
       
   513   If it returns with KErrNone it sets aData to point to the
       
   514   data in the store this id
       
   515 
       
   516 @return			error code if the stream was not found
       
   517 @internalAll
       
   518 @param				 aUid	stream id
       
   519 @param				 *&aData	returned pointer to data
       
   520 */
       
   521 HBufC8* CMsvCachedStore::GetStreamL(TUid aUid) const
       
   522 	{
       
   523 	TInt pos;
       
   524 	if(FindStream(aUid, pos) != 0)
       
   525 		User::Leave(KErrNotFound);
       
   526 	
       
   527 	return iStreams->At(pos).iBuf;
       
   528 	}
       
   529 
       
   530 
       
   531 /**
       
   532 
       
   533 The CMsvCachedStore::FindStream method
       
   534 
       
   535   Finds the stream of id aUid, if it returns with KErrNone then
       
   536   pos is set to the position of the 
       
   537   if it is not found pos is set to where is should be inserted
       
   538 
       
   539 @internalAll
       
   540 @param				 aUid
       
   541 @param				 &pos
       
   542 */
       
   543 TInt CMsvCachedStore::FindStream(TUid aUid,TInt &pos) const
       
   544 	{
       
   545 	TPairedTUidHBufC8 entry;
       
   546 	entry.iUid=aUid;
       
   547 	TKeyArrayFix key(_FOFF(TPairedTUidHBufC8,iUid),ECmpTInt32);
       
   548 	return(iStreams->FindIsq(entry,key,pos));
       
   549 	}
       
   550 
       
   551 
       
   552 /**
       
   553 
       
   554 The CMsvCachedStore::DeleteStream method
       
   555 
       
   556   deletes the stream with this id
       
   557 
       
   558 @return			error code KErrNone unless the stream wasn't found
       
   559 @internalAll
       
   560 @param				 aUid	the stream id to delete
       
   561 */
       
   562 TInt CMsvCachedStore::DeleteStream(TUid aUid)
       
   563 	{
       
   564 	__ASSERT_ALWAYS(iReaderCount==0 && iWriterCount==0,Panic(EReadingOrWritingWhileDeleteStream));
       
   565 	TInt pos;
       
   566 	TInt error=FindStream(aUid,pos);
       
   567 	if(error==KErrNone)
       
   568 		{
       
   569 		delete iStreams->At(pos).iBuf;
       
   570 		iStreams->Delete(pos);
       
   571 		}
       
   572 	return(error);
       
   573 	}
       
   574 
       
   575 
       
   576 /**
       
   577 
       
   578 The CMsvCachedStore::LoadL method
       
   579 
       
   580 loads the streams from a file
       
   581 
       
   582   should this create the file if it is corupt???
       
   583 
       
   584 @leave				leaves if we can't find the file, if we run out of memory, if the file is corrupt
       
   585 @internalAll
       
   586 @param				 &aFile	file to load the streams from, take ownership of the file
       
   587 */
       
   588 void CMsvCachedStore::LoadL(RFile &aFile)
       
   589 	{
       
   590 	__ASSERT_DEBUG(iStreams->Count()==0,User::Invariant());
       
   591 
       
   592 	// Need to cache the file size
       
   593 	User::LeaveIfError(aFile.Size(iSize));
       
   594 
       
   595 	RFileReadStream in(aFile);
       
   596 	in.PushL();
       
   597 	TCheckedUid check;
       
   598 	in >> check;
       
   599 	if(check.UidType().IsValid()==EFalse) User::Leave(KErrCorrupt);
       
   600 	if(check.UidType()[0]!=KMsvEntryFile) User::Leave(KErrCorrupt);
       
   601 	in >> *iStreams;
       
   602 	CleanupStack::PopAndDestroy(); // close RFileReadStream in
       
   603 	}
       
   604 
       
   605 
       
   606 
       
   607 /**
       
   608 
       
   609 The CMsvCachedStore::SaveL method
       
   610 
       
   611 Saves the current state to iFileName
       
   612 
       
   613 @leave				leaves if we can't replace the file, if we run out of disk space,
       
   614 @internalAll
       
   615 */
       
   616 void CMsvCachedStore::SaveL()
       
   617 	{
       
   618 	RFile tempStoreFile;
       
   619 	iStoreManager.OpenTempStoreFileL(iEntryId, tempStoreFile);
       
   620 	RFileWriteStream out(tempStoreFile);
       
   621 	out.PushL();
       
   622 	WriteToFileStreamL(out);
       
   623 	CleanupStack::PopAndDestroy(&out); // close RFileWriteStream out
       
   624 	iStoreManager.ReplaceFileStoreL(iEntryId);
       
   625 
       
   626 	// Need the size
       
   627 	RFile storeFile;
       
   628 	User::LeaveIfError(iStoreManager.OpenFileStoreForRead(iEntryId, storeFile));
       
   629 	CleanupClosePushL(storeFile);
       
   630 	User::LeaveIfError(storeFile.Size(iSize));
       
   631 	CleanupStack::PopAndDestroy(&storeFile);
       
   632 	
       
   633 
       
   634 	}
       
   635 
       
   636 void CMsvCachedStore::WriteToFileStreamL(RFileWriteStream &aOut)
       
   637 	{
       
   638 	TCheckedUid check(TUidType(KMsvEntryFile,KMsvEntryFile,KNullUid));
       
   639 	aOut << check;
       
   640 	aOut << *iStreams;
       
   641 	aOut.CommitL();	
       
   642 	}
       
   643 
       
   644 
       
   645 
       
   646 
       
   647 
       
   648 EXPORT_C void RMsvReadStream::OpenL(const CMsvStore& aMsvStore, TUid aUid)
       
   649 /** Prepares an existing stream with UID for reading.
       
   650 
       
   651 After this function has been called, the stream can be read from with the 
       
   652 functions provided by the RReadStream base class.
       
   653 
       
   654 @param aMsvStore The CMsvStore the stream is in. 
       
   655 @param aUid The UID of the stream to open with read access 
       
   656 @leave KErrNotFound There is no stream with UID aUid 
       
   657 @leave Other Standard stream leave codes. */
       
   658 	{
       
   659 	HBufC8 *buffer=aMsvStore.iStore->GetStreamL(aUid);
       
   660 	HMsvReadBuf *tidy= new (ELeave) HMsvReadBuf(*buffer, *(aMsvStore.iStore));
       
   661 	Attach(tidy);
       
   662 	}
       
   663 
       
   664 
       
   665 EXPORT_C void RMsvReadStream::OpenLC(const CMsvStore& aMsvStore,TUid aUid)
       
   666 /** Prepares an existing stream with UID for reading.
       
   667 
       
   668 After this function has been called, the stream can be read from with the 
       
   669 functions provided by the RReadStream base class.
       
   670 
       
   671 The object is placed on the cleanup stack. 
       
   672 
       
   673 @param aMsvStore The CMsvStore the stream is in. 
       
   674 @param aUid The UID of the stream to open with read access 
       
   675 @leave KErrNotFound There is no stream with UID aUid 
       
   676 @leave Other Standard stream leave codes. */
       
   677 	{
       
   678 	OpenL(aMsvStore,aUid);
       
   679 	PushL();
       
   680 	}
       
   681 
       
   682 
       
   683 
       
   684 /**
       
   685 
       
   686 The RMsvReadStream::OpenLC method
       
   687 
       
   688 ties the read stream to a HMsvReadBuf
       
   689 
       
   690 
       
   691 @leave				leaves if we can't find the stream
       
   692 @param				 aStore   aStore is the CMsvCachedStore within which we look for the stream
       
   693 @param				 aUid		id of stream to open for reading
       
   694 */
       
   695 void RMsvReadStream::OpenLC(CMsvCachedStore& aStore,TUid aUid)
       
   696 	{
       
   697 	HBufC8 *buffer=aStore.GetStreamL(aUid);
       
   698 	HMsvReadBuf *tidy= new (ELeave) HMsvReadBuf(*buffer, aStore);
       
   699 	Attach(tidy);
       
   700 	}
       
   701 
       
   702 
       
   703 
       
   704 HMsvWriteBuf* HMsvWriteBuf::NewL(TUid aUid,CMsvCachedStore& aStore)
       
   705 	{
       
   706 	HMsvWriteBuf* self=new (ELeave) HMsvWriteBuf(aUid,aStore);
       
   707 	self->PushL();
       
   708 	self->iBuf=CBufSeg::NewL(KMsvFlatBufferChunkSize);
       
   709 	CleanupStack::Pop(self);
       
   710 	self->Set(*(self->iBuf),0);
       
   711 	return(self);
       
   712 	}
       
   713 
       
   714 HMsvWriteBuf::HMsvWriteBuf(TUid aUid,CMsvCachedStore& aStore) : iBuf(NULL), iStore(&aStore), iUid(aUid)
       
   715 	{
       
   716 	iStore->iWriterCount++;
       
   717 	}
       
   718 
       
   719 void HMsvWriteBuf::DoRelease()
       
   720 	{
       
   721 	__ASSERT_DEBUG(iStore==NULL || iStore->iWriterCount>0,User::Invariant());
       
   722 	delete iBuf;
       
   723 	// we decrememt the writer count if it wasn't done in DoSynchL (called if client commits)
       
   724 	if(iStore) iStore->iWriterCount--;
       
   725 	iStore=NULL;
       
   726 	delete this;
       
   727 	}
       
   728 
       
   729 void HMsvWriteBuf::DoSynchL()
       
   730 	{
       
   731 	// if we have already sync'd it will be null so ignore the sync
       
   732 	if(iStore!=NULL)
       
   733 		{
       
   734 		__ASSERT_DEBUG(iStore->iWriterCount>0,User::Invariant());
       
   735 		TBufBuf::DoSynchL();
       
   736 		iStore->CreateOrReplaceStreamL(iUid,*iBuf);
       
   737 		// decrement the writer count, after a commit all writes are ignored, this is the
       
   738 		// same as other stores, also set iStore to NULL so we don't decrement the writer
       
   739 		// count in DoRelease as well.
       
   740 		iStore->iWriterCount--;
       
   741 		iStore=NULL;
       
   742 		}
       
   743 	}
       
   744 
       
   745 
       
   746 
       
   747 
       
   748 HMsvReadBuf::HMsvReadBuf(const TDesC8 &aBuf,CMsvCachedStore &aStore) : iCachedStore(aStore)
       
   749 	{ 
       
   750 	TUint8* ptr=(TUint8 *)aBuf.Ptr();
       
   751 	Set(ptr,ptr+aBuf.Length(),ERead);
       
   752 	aStore.iReaderCount++;
       
   753 	}
       
   754 
       
   755 void HMsvReadBuf::DoRelease()
       
   756 	{
       
   757 	__ASSERT_ALWAYS(iCachedStore.iReaderCount>0,User::Invariant());
       
   758 	iCachedStore.iReaderCount--;
       
   759 	delete this;
       
   760 	}
       
   761 
       
   762 
       
   763 EXPORT_C void RMsvWriteStream::AssignLC(CMsvStore &aMsvStore, TUid aUid)
       
   764 /** Prepares a stream for writing; the object is placed on the cleanup stack. 
       
   765 
       
   766 After this function has been called, the stream can be written to with the 
       
   767 functions provided by the RWriteStream base class.
       
   768 
       
   769 If the stream does not exist, it is created.
       
   770 
       
   771 @param aMsvStore The CMsvStore the stream is in 
       
   772 @param aUid The UID of the stream to open with write access 
       
   773 @leave KErrAccessDenied Store is not open for writing 
       
   774 @leave Other Standard stream leave codes */
       
   775 	{
       
   776 	if (aMsvStore.iLockStatus==CMsvStore::EMsvStoreUnlocked)
       
   777 		User::Leave(KErrAccessDenied);
       
   778 	AssignL(aMsvStore,aUid);
       
   779 	PushL();
       
   780 	}
       
   781 
       
   782 EXPORT_C void RMsvWriteStream::AssignL(CMsvStore &aMsvStore, TUid aUid)
       
   783 /** Prepares a stream for writing. 
       
   784 
       
   785 After this function has been called, the stream can be written to with the 
       
   786 functions provided by the RWriteStream base class.
       
   787 
       
   788 If the stream does not exist, it is created.
       
   789 
       
   790 @param aMsvStore The CMsvStore the stream is in 
       
   791 @param aUid The UID of the stream to open with write access 
       
   792 @leave KErrAccessDenied Store is not open for writing 
       
   793 @leave Other Standard stream leave codes */
       
   794 	{
       
   795 	if (aMsvStore.iLockStatus==CMsvStore::EMsvStoreUnlocked)
       
   796 		User::Leave(KErrAccessDenied);
       
   797 
       
   798 	Attach(HMsvWriteBuf::NewL(aUid,*(aMsvStore.iStore)));
       
   799 	}
       
   800 
       
   801 void RMsvWriteStream::AssignLC(CMsvCachedStore &aStore, TUid aUid)
       
   802 	{
       
   803 	Attach(HMsvWriteBuf::NewL(aUid,aStore));
       
   804 	PushL();
       
   805 	}