diff -r 000000000000 -r 8e480a14352b messagingfw/msgsrvnstore/server/src/MSVSTORE.CPP --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/messagingfw/msgsrvnstore/server/src/MSVSTORE.CPP Mon Jan 18 20:36:02 2010 +0200 @@ -0,0 +1,1085 @@ +// Copyright (c) 1998-2009 Nokia Corporation and/or its subsidiary(-ies). +// All rights reserved. +// This component and the accompanying materials are made available +// under the terms of "Eclipse Public License v1.0" +// which accompanies this distribution, and is available +// at the URL "http://www.eclipse.org/legal/epl-v10.html". +// +// Initial Contributors: +// Nokia Corporation - initial contribution. +// +// Contributors: +// +// Description: +// MSVSTORE.CPP +// + +#include + + +#include "MSVSTD.H" +#include "MSVSTORE.H" +#include "MSVPANIC.H" +#include "CMsvCachedStore.h" +#include "cmsvbodytext.h" +#include +#include "CMsvAttachmentManager.h" +#include +#include +#include +#include +#ifdef SYMBIAN_ENABLE_SPLIT_HEADERS +#include "msvconsts.h" +#endif + + +// +// CMsvStore +// +const TUint8 KCarriageReturn = 0x0D; +const TUint8 KLineFeed = 0x0A; + +EXPORT_C CMsvStore::~CMsvStore() +// +// +// +/** Destructor. + +If the message store is currently locked, the destructor releases it before +deleting the object. */ + { + // tell the observer that this store is being released/closed + if (iConstructed) + { + // only inform server if the store was successfully opened + if (iLockStatus==EMsvStoreLocked) + iObserver.HandleStoreEvent(MMsvStoreObserver::EMsvEditStoreClosed, iId); + else + iObserver.HandleStoreEvent(MMsvStoreObserver::EMsvReadStoreClosed, iId); + } + + delete iAttachmentManager; + + delete iStore; + delete iBodyText; + } + +EXPORT_C void CMsvStore::StoreBodyTextL(const CRichText& aRichTextBody) +// +// stores and commits body text to the file store, overwriting any existing data +// will panic if the store is unlocked and will leave if no store is found +// +/** Stores the body text stream of the message store. Any existing +data is overwritten. Write access is needed for this function. A commit must be done +following this function for the new data to be retained. + +@param aRichTextBody The body data to be externalised +@leave KErrAccessDenied Store is not open for writing +@leave Other Standard streaming leave codes */ + { + if (iLockStatus==EMsvStoreUnlocked || iStore==NULL) + User::Leave(KErrAccessDenied); + + iBodyText->RemoveL(*this); + + // Remove the body text data if stored in KMsvPlainBodyText8 or KMsvPlainBodyText16 format. + if (IsPresentL(KMsvPlainBodyText8)) + { + RemoveL(KMsvPlainBodyText8); + } + if (IsPresentL(KMsvPlainBodyText16)) + { + RemoveL(KMsvPlainBodyText16); + } + + RMsvWriteStream out; + out.AssignL(*this,KMsvEntryRichTextBody); + CEmbeddedStore* embeddedStore=CEmbeddedStore::NewLC(out); + TStreamId streamId=aRichTextBody.StoreL(*embeddedStore); + embeddedStore->SetRootL(streamId); + embeddedStore->CommitL(); + CleanupStack::PopAndDestroy(); //embeddedstore + } + +void CMsvStore::Lock() + { + iLockStatus=EMsvStoreLocked; + } + +EXPORT_C TBool CMsvStore::IsNullL() const +/** Tests whether the message store contains any streams. +@return ETrue if the store has no streams, else EFalse +*/ + { + return iStore->IsNullL(); + } + +EXPORT_C TBool CMsvStore::IsPresentL(TUid aUid) const +/** Tests whether the message store contains a stream identifier. +Do not use to check if there is a body text part stored with the email; +use CMsvStore::HasBodyTextL() instead. +@param aUid Identifier of stream +@return ETrue if the store has a stream aUid, else EFalse + */ + { + return iStore->IsPresentL(aUid); + } + + +EXPORT_C TBool CMsvStore::HasBodyTextL() const +/** Checks if the store has a body text stream; IsPresentL(KMsvEntryRichTextBody) +will always return EFalse when the store_8bit_flag in imcm.rss is enabled. +@return ETrue if the store has a body text stream, else EFalse +*/ + { + return iStore->IsPresentL(KMsvEntryRichTextBody) || iBodyText->IsPresentL(*this)|| iStore->IsPresentL(KMsvPlainBodyText8)|| iStore->IsPresentL(KMsvPlainBodyText16); + } + +/** +Restores body text into the given rich text object - doesnt matter if store is locked or not +will leave if the file store doesn't exist, the body text does not exist, and also propagate store leaves +Reads the body text stream from the message store into the given rich text +object. +@param aRichTextBody On return, the message store's body text is inserted + into this object. Any previously existing contents is lost. +@leave KErrNotFound There is no body text stream in the store +@leave Other Standard streaming leave codes +*/ +EXPORT_C void CMsvStore::RestoreBodyTextL(CRichText& aRichTextBody) + { + // Charset set to 0 so that RestoreBodyTextL works as per existing published behaviour. + RestoreBodyTextL(aRichTextBody, 0); + } + +/** +Restores body text into the given rich text object - doesnt matter if store is locked or not. +Reads the body text stream from the message store into the given rich text +object. +@param aRichTextBody On return, the message store's body text is inserted + into this object. Any previously existing contents is lost. +@param aCharsetOverride The charset with which to override the existing charset + when data is stored a 8 bit format. +@leave KErrNotFound There is no body text stream in the store +@leave Other Standard streaming leave codes +*/ +EXPORT_C void CMsvStore::RestoreBodyTextL(CRichText& aRichTextBody, TUint aCharsetOverride) + { + if (iStore==NULL ) + { + User::Leave(KErrNotFound); + } + + if (IsPresentL(KMsvEntryRichTextBody)) + { + RMsvReadStream inputStream; + inputStream.OpenL(*this, KMsvEntryRichTextBody); // CEmbeddedStore::FromLC() take ownership + CEmbeddedStore* embeddedStore = CEmbeddedStore::FromLC(inputStream); + aRichTextBody.RestoreL(*embeddedStore, embeddedStore->Root()); + CleanupStack::PopAndDestroy(); // embeddedStore + } + else if(iBodyText->IsPresentL(*this)) + { + iBodyText->RestoreL(*this); + // If a new charset was set, override the restored charset + // so that data is converted using new charset. + if(aCharsetOverride != 0) + { + iBodyText->SetCharacterSet(aCharsetOverride); + } + iBodyText->GetBodyTextL(iFs, *this, aRichTextBody); + } + else + { + if(IsPresentL(KMsvPlainBodyText8) || IsPresentL(KMsvPlainBodyText16)) + { + RestorePlainBodyTextL (aRichTextBody, aCharsetOverride); + } + else + { + User::Leave(KErrNotFound); + } + } + } + + + + +/** +Restores a CRichText object from the plain body text file. +@param aRichText On completion this contains the plain body text. +@param aCharsetOverride The new charset with which to override the existing charset + when data is stored a 8 bit plain text format. +@return void. +*/ +void CMsvStore::RestorePlainBodyTextL(CRichText& aRichText, TUint aCharsetOverride) + { + RMsvReadStream inputStream; + TBool is8Bit = EFalse; + TUint charSet = 0; + TUint defaultCharSet = 0; + if(IsPresentL(KMsvPlainBodyText8)) + { + inputStream.OpenLC(*this, KMsvPlainBodyText8); + charSet = inputStream.ReadUint32L(); + defaultCharSet = inputStream.ReadUint32L(); + is8Bit = ETrue; + } + else + { + inputStream.OpenLC(*this, KMsvPlainBodyText16); + } + // If a new charset was set, override the restored charset so that + // data is converted using new charset. + if(aCharsetOverride!=0) + { + charSet = aCharsetOverride; + } + + TBool committed = inputStream.ReadUint32L(); + TFileName filePath; + HBufC* fileName = HBufC::NewLC(inputStream, KMaxFileName); + RFile bodyTextFile; + CleanupClosePushL(bodyTextFile); + + iStoreManager.BodyTextFilePathL(iId, filePath); + + filePath.Append(*fileName); + iStoreManager.OpenBodyTextFileForReadL(bodyTextFile, iId, filePath); + if(is8Bit) + { + GetRichTextFrom8BitL(bodyTextFile, aRichText, charSet, defaultCharSet); + } + else + { + GetRichTextFrom16BitL(bodyTextFile, aRichText); + } + + CleanupStack::PopAndDestroy(3, &inputStream);//bodyTextFile,fileName,in + } +/** +Restores 8 bit body text from the Message Store +@param aInputStream on completion the RFileReadStream contains the message body text stream. +*/ +void CMsvStore::Restore8BitBodyTextL(RFileReadStream& aInputStream) + { + RMsvReadStream in; + in.OpenLC(*this, KMsvPlainBodyText8); + in.ReadUint32L(); // reads charset + in.ReadUint32L(); // read default charset + in.ReadUint32L(); // returns ETrue if committed to message store else EFalse + TFileName filePath; + HBufC* fileName = HBufC::NewLC(in, KMaxFileName); + RFile bodyTextFile; + CleanupClosePushL(bodyTextFile); + iStoreManager.BodyTextFilePathL(iId, filePath); + filePath.Append(*fileName); + iStoreManager.OpenBodyTextFileForReadL(bodyTextFile, iId, filePath); + aInputStream.Attach(bodyTextFile, 0); + CleanupStack::PopAndDestroy(3, &in); // bodyTextFile, fileName, in + } + +/** +Gets CRichText from plain body text file if data stored as 8 bit. +@param aFile The file containing the plain body text. +@param aRichText The CRichText object that will be filled on return. +@param aCharSet The charset of the body part. +@param aDefaultCharSet The default charset of the system. +@return void. +*/ +void CMsvStore::GetRichTextFrom8BitL(RFile& aBodyTextFile, CRichText& aRichText, TUint aCharSet, TUint aDefaultCharSet) + { + Convert8BitToRichTextL(aBodyTextFile, aRichText, aCharSet, aDefaultCharSet); + } + + +/** +Gets CRichText from plain body text file if data stored as 16 bit. +@param aFile The file containing the plain body text. +@param aRichText The CRichText object that will be filled on return. +@return void. +*/ +void CMsvStore::GetRichTextFrom16BitL(RFile& aBodyTextFile, CRichText& aRichText) + { + TInt size = 0; + aBodyTextFile.Size(size); + TBuf8 buf; + TBool carriageReturn = EFalse; + while(size > 0) + { + aBodyTextFile.Read(buf); + // Divide by 2 since the 16-bit buffer was stored using 8-bit pointer. + TPtrC16 bodyTextPtr((TUint16*)(buf.Ptr()), buf.Length()/2); + + // Was the last character of the last block a carriage return. + // If so we need to check for the specific condition where the carriage + // return / line feed has been split across blocks in which case the line + // feed should be discarded and the special character ELineBreak inserted + // instead. If the first character of this new block is not line feed + // then we should insert the carriage return as it is required in the + // output data and has not been added yet. + if (carriageReturn) + { + if (bodyTextPtr[0] == KLineFeed) + { + aRichText.InsertL(aRichText.DocumentLength(), CEditableText::ELineBreak); + bodyTextPtr.Set(bodyTextPtr.Mid(1)); + } + else + { + aRichText.InsertL(aRichText.DocumentLength(), TChar(KCarriageReturn)); + } + + carriageReturn = EFalse; + } + + TInt start = 0; + TInt len = bodyTextPtr.Length(); + TInt i = 0; + + // Insert the data read from the RFile to CRichText.If there is CRLF insert + // CEditableText::ELineBreak + for(i=1; iPrepareToConvertToOrFromL(aCharSet, iFs); + } + if (available == CCnvCharacterSetConverter::ENotAvailable) + { + available = converter->PrepareToConvertToOrFromL(aDefaultCharSet, iFs); + } + if (available != CCnvCharacterSetConverter::EAvailable) + { + User::Leave(KErrNotSupported); + } + + HBufC8* inBuf = HBufC8::NewLC(KMsvDecodeChunkLength); + HBufC16* outBuf = HBufC16::NewLC(KMsvDecodeChunkLength); + TPtr8 inPtr = inBuf->Des(); + TPtr16 outPtr = outBuf->Des(); + + // Used to preserve state across multiple calls to ConvertToUnicode. + TInt state = CCnvCharacterSetConverter::KStateDefault; + TBool newLine = EFalse; + TBool newPara = EFalse; + TInt bytesRemaining = sourceStream->SizeL(); + + while(bytesRemaining > 0) + { + // Set the buffer length to the smaller of the number of bytes remaining, + // or the chunk length. + inPtr.SetLength(bytesRemaining < KMsvDecodeChunkLength ? bytesRemaining : KMsvDecodeChunkLength); + // Read data from stream up to and including the 1st LF encountered. + TRAPD(err, inputStream.ReadL(inPtr,TChar(KLineFeed))); + if (err != KErrEof) + { + User::LeaveIfError(err); + } + + TInt inBufLength = inPtr.Length(); + __ASSERT_DEBUG(inBufLength > 0, PanicServer(EMsvInputBufferEmpty)); + bytesRemaining -= inBufLength; + + // If the data read is terminated with an LF or CRLF, remove it and mark it for + // appending a rich text line end or paragraph delimiter. + TInt bytesTruncated = 0; + if (inPtr[inBufLength - 1] != KLineFeed) + { + // The data read does not contain any new line or paragraph delimters. + newLine = EFalse; + newPara = EFalse; + } + else + { + // Data read is terminated with LF. Truncate length of data to ignore LF or CRLF bytes. + if (inBufLength > 1 && inPtr[inBufLength - 2] == KCarriageReturn) + { + bytesTruncated = 2; + inBufLength -= bytesTruncated; + inPtr.SetLength(inBufLength); // Remove CRLF. + } + else + { + bytesTruncated = 1; + inBufLength -= bytesTruncated; + inPtr.SetLength(inBufLength); // Remove LF. + } + + // Work out if it should be a new line or new paragraph. + if (inBufLength == 0) + { + if (newLine) + { + // There are more than two new line delimiters in a row with no data + // between them - new paragraph. + newLine = EFalse; + newPara = ETrue; + } + else + { + newLine = ETrue; + newPara = EFalse; + } + } + else + { + // It's a new line. + newLine = ETrue; + newPara = EFalse; + } + } + + // Convert the 8 bit data to unicode. + TInt bytesUnconverted = converter->ConvertToUnicode(outPtr, inPtr, state); + User::LeaveIfError(bytesUnconverted); + if (bytesUnconverted > 0) + { + // Some bytes could not be converted because the output buffer was too small. + // Seek back to the position of the 1st unconverted byte and recalculate the bytes remaining. + TInt bytesSeekBack = bytesUnconverted + bytesTruncated; + sourceStream->SeekL(MStreamBuf::ERead, EStreamMark, -bytesSeekBack); + bytesRemaining += bytesSeekBack; + newLine = EFalse; + newPara = EFalse; + } + + // There is no AppendL method for CRichText. Insert decoded text at end of document instead. + aRichText.InsertL(aRichText.DocumentLength(), outPtr); + + // Insert a new line or paragraph delimiter if necessary. + if (newLine) + { + aRichText.InsertL(aRichText.DocumentLength(), CEditableText::ELineBreak); + } + + if (newPara) + { + aRichText.InsertL(aRichText.DocumentLength(), CEditableText::EParagraphDelimiter); + } + } + CleanupStack::PopAndDestroy(4, &inputStream); //outBuf,inBuf,converter,inputStream + } + + +EXPORT_C void CMsvStore::DeleteBodyTextL() +// +// Deletes the body text stream +// +/** Deletes the stream that contains the body text. Write access is needed for +this function. + +@leave KErrAccessDenied Store is not open for writing +@leave Other Standard streaming leave codes */ + { + if (IsPresentL(KMsvEntryRichTextBody)) + RemoveL(KMsvEntryRichTextBody); + + // Remove the body text data if stored in KMsvPlainBodyText8 or KMsvPlainBodyText16 format. + if (IsPresentL(KMsvPlainBodyText8)) + { + RemoveL(KMsvPlainBodyText8); + } + if (IsPresentL(KMsvPlainBodyText16)) + { + RemoveL(KMsvPlainBodyText16); + } + + iBodyText->RemoveL(*this); + } + + +EXPORT_C void CMsvStore::DeleteL() +// +// Deletes the file store +// +/** Deletes the message store. After a delete, the behaviour of the object is undefined: +it can only be deleted. + +Write access is needed for this function. + +@leave KErrAccessDenied The store is read only +@leave Other Standard file store error codes */ + { + if (iStore==NULL) + return; + + if (iLockStatus==EMsvStoreUnlocked) + User::Leave(KErrAccessDenied); + + iStore->DeleteL(); + delete iStore; + iStore=NULL; + } + + +EXPORT_C TInt CMsvStore::Commit() +// +// +// +/** Commits changes to the message store, returning any error code. + +Committing changes makes these changes permanent, and means that the store +cannot be rolled back to a state before the changes were begun. + +You should use this function before deleting a CMsvStore, if you have made +changes to it through RMsvWriteStream . Note that StoreBodyTextL() performs +a commit itself, so an additional commit is not required after its use. + +The functions is identical to the following one, except that it returns an +error code if an error occurs. + +Write access is needed. + +@return Changes committed successfully +@return Store open for read only +@return Unable to commit changes */ + { + if (iLockStatus==EMsvStoreUnlocked || iStore==NULL) + return KErrAccessDenied; + + TInt error = KErrNone; + + // Save the attachment information if there is any... + if( iAttachmentManager != NULL ) + { + TRAP(error, iAttachmentManager->StoreL()); + if( error < KErrNone ) + { + // error occured trying to save the attachments + return error; + } + } + // commit the store + error = iStore->Commit(); + if( iAttachmentManager != NULL && error==KErrNone ) + { + iAttachmentManager->HandleCommitComplete(); + } + return error; + } + + +EXPORT_C void CMsvStore::CommitL() +// +// +// +/** Commits changes to the message store, leaving if an error occurs. + +Committing changes makes these changes permanent, and means that the store +cannot be rolled back to a state before the changes were begun. + +You should use this function before deleting a CMsvStore, if you have made +changes to it through RMsvWriteStream . Note that StoreBodyTextL() performs +a commit itself, so an additional commit is not required after its use. + +The functions is identical to the previous one, except that it leaves with +the error code if an error occurs. + +Write access is needed. + +@leave KErrAccessDenied Store open for read only +@leave Standard streaming error codes Unable to commit changes */ + { + User::LeaveIfError(Commit()); + } + + +EXPORT_C void CMsvStore::Remove(TUid aUid) +// +// +// +/** Deletes the identified stream from the store. The function returns, whether +or not it completes successfully. + +Write access is needed for this function. + +@param aUid The UID of the stream to delete */ + { +#if (defined SYMBIAN_MESSAGESTORE_HEADER_BODY_USING_SQLDB) + TRAP_IGNORE(RemoveL(aUid)); +#else + if (iLockStatus==EMsvStoreUnlocked || iStore==NULL) + return; + + if((aUid == KMsvPlainBodyText16)|| aUid == (KMsvPlainBodyText16)) + { + TRAP_IGNORE(iStoreManager.DeletePlainTextFileL(iId)); + } + + iStore->Remove(aUid); +#endif + } + + + + +EXPORT_C void CMsvStore::RemoveL(TUid aUid) +// +// +// +/** Deletes the identified stream from the store. It leaves if it cannot complete +successfully. + +Write access is needed for this function. + +@param aUid The UID of the stream to delete +@leave KErrAccessDenied The store is read only +@leave Other Standard streaming error codes */ + { + if (iLockStatus==EMsvStoreUnlocked || iStore==NULL) + User::Leave(KErrAccessDenied); + if((aUid == KMsvPlainBodyText16)|| aUid == (KMsvPlainBodyText16)) + { +#if (defined SYMBIAN_MESSAGESTORE_HEADER_BODY_USING_SQLDB) + TRAP_IGNORE(iStoreManager.DeletePlainTextFileL(iId)); +#else + iStoreManager.DeletePlainTextFileL(iId); +#endif + } + +#if (defined SYMBIAN_MESSAGESTORE_HEADER_BODY_USING_SQLDB) + iStore->Remove(aUid); +#else + iStore->RemoveL(aUid); +#endif + } + + + + +EXPORT_C void CMsvStore::Revert() +// +// +// +/** Reverts the store to the previous commit level. This removes all changes that +have been made to the store since the last commit. + +The function cannot leave: it returns, whether or not it completes successfully. + +Write access is needed for this function. */ + { + if (iLockStatus==EMsvStoreUnlocked || iStore==NULL) + return; + + iStore->Revert(); // Check this for 2073 + + // load the attachment infomation if already loaded + if( iAttachmentManager != NULL ) + { + TRAP_IGNORE(iAttachmentManager->RestoreL()); // ignore any errors + } + } + + + +EXPORT_C void CMsvStore::RevertL() +// +// +// +/** Reverts the store to the previous commit level. This removes all changes that +have been made to the store since the last commit. + +The function leaves if it cannot complete successfully. + +Write access is needed for this function. + +@leave KErrAccessDenied The store is read only +@leave Other Standard streaming error codes */ + { + if (iLockStatus==EMsvStoreUnlocked || iStore==NULL) + User::Leave(KErrAccessDenied); + + iStore->RevertL(); + + // load the attachment infomation if already loaded + if( iAttachmentManager != NULL ) + { + iAttachmentManager->RestoreL(); + } + } + +EXPORT_C TInt CMsvStore::SizeL() +// +// Returns the size of the store, or zero if the file doesn't exist +// +/** Gets the size of the message store. + +@return Size of the message store in bytes */ + { + if (iStore==NULL) + User::Leave(KErrNotFound); + + return iStore->Size(); + } + + + +/** +@internalComponent +*/ +EXPORT_C CMsvStore* CMsvStore::OpenForReadL(MMsvStoreObserver& aObserver, RFs& aFs, MMsvStoreManager& aStoreManager, TMsvId aId) + { + CMsvStore* store=new(ELeave) CMsvStore(aObserver, aFs, aId, aStoreManager); + CleanupStack::PushL(store); + store->ConstructL(ETrue); + CleanupStack::Pop(store); + return store; + } + +/** +@internalComponent +*/ +EXPORT_C CMsvStore* CMsvStore::OpenForWriteL(MMsvStoreObserver& aObserver, RFs& aFs, MMsvStoreManager& aStoreManager, TMsvId aId) + { + CMsvStore* store=new(ELeave) CMsvStore(aObserver, aFs, aId, aStoreManager); + CleanupStack::PushL(store); + store->Lock(); + store->ConstructL(EFalse); + CleanupStack::Pop(store); + return store; + } + +/** +@internalComponent +*/ +EXPORT_C CMsvStore::CMsvStore(MMsvStoreObserver& aObserver, RFs& aFs, TMsvId aId, MMsvStoreManager& aStoreManager) +: iLockStatus(EMsvStoreUnlocked), iFs(aFs), iObserver(aObserver), iId(aId), iConstructed(EFalse), iStoreManager(aStoreManager) + {} + + + + +void CMsvStore::ConstructL(TBool aReadOnly) + { + iStore=CMsvCachedStore::OpenL(iId, iStoreManager, aReadOnly); + iBodyText = CMsvBodyText::NewL(); + iConstructed=ETrue; + } + + +/** +Returns an interface for the Attachment Manager. + +This methods returns an interface that can be used to provided attachment +management functionality for each message entry. + +@return A reference to the Attachment Manager interface +@see MMsvAttachmentManager +*/ +EXPORT_C MMsvAttachmentManager& CMsvStore::AttachmentManagerL() + { + if( iAttachmentManager==NULL ) + { + TBool isStoreReadOnly = (iLockStatus == EMsvStoreUnlocked ? ETrue : EFalse); + iAttachmentManager = CMsvAttachmentManager::NewL(*this, iStoreManager, iId, iFs, isStoreReadOnly); + } + + MMsvAttachmentManager& attachmentAPI = *iAttachmentManager; + return attachmentAPI; + } + +EXPORT_C MMsvAttachmentManagerSync& CMsvStore::AttachmentManagerExtensionsL() + { + if( iAttachmentManager==NULL ) + { + TBool isStoreReadOnly = (iLockStatus == EMsvStoreUnlocked ? ETrue : EFalse); + iAttachmentManager = CMsvAttachmentManager::NewL(*this, iStoreManager, iId, iFs, isStoreReadOnly); + } + + return (MMsvAttachmentManagerSync&) *iAttachmentManager; + } + +/** +@internalTechnology +@released +*/ +EXPORT_C void CMsvStore::CreateShareProtectedAttachmentL(const TDesC& aFileName, RFile& aAttachmentFile, CMsvAttachment* aAttachmentInfo) + { + if (iAttachmentManager == NULL) + { + TBool isStoreReadOnly = (iLockStatus == EMsvStoreUnlocked ? ETrue : EFalse); + iAttachmentManager = CMsvAttachmentManager::NewL(*this, iStoreManager, iId, iFs, isStoreReadOnly); + } + + iAttachmentManager->CreateShareProtectedAttachmentL(aFileName, aAttachmentFile, aAttachmentInfo); + } + + +/** +Intialise and return the CMsvPlainBodyText object that can be used for reading/writing plain body text. +@param aIs8Bit TBool indicating whether to store bdy text as 8/16 bit. +@param aCharsetId The charset of the body part. +@param aDefaultCharsetId The default charset of the system. +@leave KErrAccessDenied If Store is opened in Read mode. +@return CMsvPlainBodyText. +*/ +EXPORT_C CMsvPlainBodyText* CMsvStore::InitialisePlainBodyTextForWriteL(TBool aIs8Bit, TUint aCharsetId, TUint aDefaultCharsetId) + { + if(iLockStatus != EMsvStoreLocked) + { + User::Leave(KErrAccessDenied); + } + return CMsvPlainBodyText::NewL(iStoreManager, *this, aIs8Bit, aCharsetId, aDefaultCharsetId, iId, iFs); + } + + +/** +Intialise and return the CMsvPlainBodyText object that can be used for reading plain body text. +@param aChunkLength The length of the chunk that will be processed while reading. +@leave KErrAccessDenied If Store is opened in Write mode. +@return CMsvPlainBodyText. +*/ +EXPORT_C CMsvPlainBodyText* CMsvStore::InitialisePlainBodyTextForReadL(TInt aChunkLength) + { + if(iLockStatus == EMsvStoreLocked) + { + User::Leave(KErrAccessDenied); + } + return CMsvPlainBodyText::NewL(iStoreManager, *this, iId, iFs, aChunkLength); + } + + + +#if (defined SYMBIAN_MESSAGESTORE_HEADER_BODY_USING_SQLDB) + +/** +Construct the CacheEntry. +@param aMtmId A TUid. +@param aIsBodyEntry A TEntryStoreType. +@return None. +@internalComponent +*/ + +void CMsvStore::ConstructDbL(TUid aMtmId,TBool aReadOnly) + { + iStore=CMsvCachedStore::OpenL(iId, iStoreManager, aReadOnly,aMtmId); + iStore->iMtmId = aMtmId; + iBodyText = CMsvBodyText::NewL(); + iConstructed=ETrue; + } + +/** +Open the Store for read. +@param aObserver A MMsvStoreObserver as reference. +@param aFs A RFs as reference. +@param aStoreManager A MMsvStoreManager as reference. +@param aId A TMsvId +@param aMtmId A TUid. +@param aIsBodyEntry A TEntryStoreType +@return CMsvStore* +@internalComponent +*/ + +EXPORT_C CMsvStore* CMsvStore::OpenForReadL(MMsvStoreObserver& aObserver, RFs& aFs, MMsvStoreManager& aStoreManager, TMsvId aId, TUid aMtmId) + { + CMsvStore* store=new(ELeave)CMsvStore(aObserver, aFs, aId, aStoreManager); + CleanupStack::PushL(store); + store->ConstructDbL(aMtmId,ETrue); + CleanupStack::Pop(store); + return store; + } + + +/** +Open the Store for write. +@param aObserver A MMsvStoreObserver as reference. +@param aFs A RFs as reference. +@param aStoreManager A MMsvStoreManager as reference. +@param aId A TMsvId +@param aMtmId A TUid. +@param aIsBodyEntry A TEntryStoreType +@return CMsvStore* +@internalComponent +*/ + +EXPORT_C CMsvStore* CMsvStore::OpenForWriteL(MMsvStoreObserver& aObserver, RFs& aFs, MMsvStoreManager& aStoreManager, TMsvId aId, TUid aMtmId) + { + CMsvStore* store=new(ELeave)CMsvStore(aObserver, aFs, aId, aStoreManager); + CleanupStack::PushL(store); + store->ConstructDbL(aMtmId,EFalse); + store->Lock(); + CleanupStack::Pop(store); + return store; + } + +/** +Restore the Header entry. +@param None. +@return None. +@internalComponent +*/ +void CMsvStore::RestoreL() + { + if (iStore==NULL ) + { + User::Leave(KErrNotFound); + } + + iStoreManager.LoadHeaderEntryL(iStore->iMtmId, iId, iStore->iHeaderFieldList); + } + + +/** +Create or Update the Header entry. +@param None. +@return None. +@internalComponent +*/ +void CMsvStore::CommitHeaderL() + { + TInt error = KErrNone; + if(!iStore->isNewEntry) + { + TRAP(error, iStoreManager.UpdateHeaderEntryL(iStore->iMtmId, iId, iStore->iHeaderFieldList)); + } + else + { + TRAP(error, iStoreManager.CreateHeaderEntryL(iStore->iMtmId, iId, iStore->iHeaderFieldList)); + iStore->isNewEntry = EFalse; + } + User::LeaveIfError(error); + } + +/** +Returns ETrue if entries stored in database +*/ +EXPORT_C TBool CMsvStore::IsDbStore() + { + return iStore->isDbStore; + } + + +/** Create TMsvWriteStore to read message store. + +@param aMsvStore The aMsvStore as reference. +@return TMsvWriteStore write sore. + */ +EXPORT_C TMsvWriteStore::TMsvWriteStore(CMsvStore& aMsvStore):iMsvStore(aMsvStore) + { + } + +/** +Assign the header Fields in to header Field list. +@param aHeaderFields : CHeaderFields* +@return None. +*/ + +EXPORT_C void TMsvWriteStore::AssignL(CHeaderFields* aHeaderFields) + { + iMsvStore.iStore->AssignL(aHeaderFields); + } + +/** +Commit the header entry to message store + +@param None. +@return None. +*/ + +EXPORT_C void TMsvWriteStore::CommitL() + { + iMsvStore.CommitHeaderL(); + } + + +/** Create TMsvReadStore to read message store. + +@param aMsvStore The aMsvStore as reference. +@param aUid The UID. +@return TMsvReadStore read sore. + */ + + +EXPORT_C TMsvReadStore::TMsvReadStore(CMsvStore& aMsvStore, TUid aUid): +iMsvStore(aMsvStore), iUid(aUid) + { + } + + +/** Load the Header entry from message store. + +@param aHeaderFields The CHeaderFields as pointer reference. +@return None. + */ + + +EXPORT_C void TMsvReadStore::LoadL(CHeaderFields*& aHeaderFields) + { + iMsvStore.RestoreL(); + iMsvStore.iStore->GetHeaderL(iUid, aHeaderFields); + } + + +/** Read the Header entry from message store. + +@param aHeaderFields The CHeaderFields as pointer reference. +@return None. + */ + + +EXPORT_C void TMsvReadStore::ReadL(CHeaderFields*& aHeaderFields) + { + iMsvStore.iStore->GetHeaderL(iUid, aHeaderFields); + } + + +#endif //#if (defined SYMBIAN_MESSAGESTORE_HEADER_BODY_USING_SQLDB)