--- a/cbs/CbsServer/ServerSrc/CCbsDbImpTopicMessages.cpp Mon Aug 23 15:50:31 2010 +0300
+++ /dev/null Thu Jan 01 00:00:00 1970 +0000
@@ -1,1720 +0,0 @@
-/*
-* Copyright (c) 2003 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: This module contains the implementation of CCbsDbImpTopicMessages class
-* member functions.
-*
-*/
-
-
-
-// INCLUDE FILES
-
-#include <e32svr.h>
-
-#include <shareddataclient.h>
-
-#include "CbsServerPanic.h"
-#include "CbsStreamHelper.h"
-#include "CbsUtils.h"
-#include "CbsDbConstants.h"
-#include "CCbsDbImpTopicList.h"
-#include "CCbsDbImpTopicMessages.h"
-#include "CCbsRecEtel.h"
-#include "CCbsReceiverHelper.h"
-
-#include "CbsLogger.h"
-
-// CONSTANTS
-
-// Expected maximum number of locked messages at once.
-const TInt KDefaultSpaceForLockedMessages = 1;
-
-// CB message header size in bytes.
-const TInt KCbMessageHeaderSize = 16;
-
-// The space used for the header of messages stream
-const TInt KMessageRootStreamSize = 6;
-
-/// The space used by one message in the messages stream
-const TInt KMessageEntrySize = 3;
-
-// Default space reserved for topic messages in message stream
-const TInt KDefaultSpaceForMessages = 6;
-
-// Space for reading messages
-const TInt KReadMessageSize = 92;
-
-
-// ================= MEMBER FUNCTIONS =======================
-
-// -----------------------------------------------------------------------------
-// CCbsDbImpTopicMessages::CCbsDbImpTopicMessages
-// C++ default constructor can NOT contain any code, that
-// might leave.
-// -----------------------------------------------------------------------------
-//
-CCbsDbImpTopicMessages::CCbsDbImpTopicMessages(
- CCbsDbImpTopicList& aTopicList,
- RFs& aFs )
- :iTopicList( aTopicList ),
- iCacheValid( EFalse ),
- iCachedTopicNumber( 0 ),
- iFs( aFs )
- {
- }
-
-// -----------------------------------------------------------------------------
-// CCbsDbImpTopicMessages::ConstructL
-// Symbian 2nd phase constructor can leave.
-// -----------------------------------------------------------------------------
-//
-void CCbsDbImpTopicMessages::ConstructL()
- {
- // Allocate the default size for the message list.
- iMessageList =
- new ( ELeave ) CArrayFixFlat< TCbsDbImpTopicMessagesCacheItem >
- ( KCbsDbMaxReceivedMessages + KCbsDbMaxSavedMessages );
-
- // Allocate the array for locked messages.
- iLockedMessages = new ( ELeave ) CArrayFixFlat< TCbsDbMessageHandle >
- ( KDefaultSpaceForLockedMessages );
- }
-
-// -----------------------------------------------------------------------------
-// CCbsDbImpTopicMessages::NewL
-// Two-phased constructor.
-// -----------------------------------------------------------------------------
-//
-CCbsDbImpTopicMessages* CCbsDbImpTopicMessages::NewL(
- CCbsDbImpTopicList& aTopicList, RFs& aFs )
- {
- CCbsDbImpTopicMessages* self =
- new ( ELeave ) CCbsDbImpTopicMessages( aTopicList, aFs );
- CleanupStack::PushL( self );
- self->ConstructL();
- CleanupStack::Pop();
- return self;
- }
-
-
-// Destructor
-CCbsDbImpTopicMessages::~CCbsDbImpTopicMessages()
- {
- CBSLOGSTRING("CBSSERVER: >>> CCbsDbImpTopicMessages::~CCbsDbImpTopicMessages()");
- // Invalidate cache.
- InvalidateCache();
-
- // And then delete the message list.
- delete iMessageList;
-
- // Delete locked messages.
- delete iLockedMessages;
- CBSLOGSTRING("CBSSERVER: <<< CCbsDbImpTopicMessages::~CCbsDbImpTopicMessages()");
- }
-
-// -----------------------------------------------------------------------------
-// CCbsDbImpTopicMessages::InvalidateCache
-// Resets the cache to default values.
-// (other items were commented in a header).
-// -----------------------------------------------------------------------------
-//
-void CCbsDbImpTopicMessages::InvalidateCache()
- {
- // Initialize members back to default.
- iCacheValid = EFalse;
- iCachedTopicNumber = 0;
-
- // Resize the message list. After the call is made, the
- // array is empty.
- if ( iMessageList )
- {
- iMessageList->Reset();
- }
- }
-
-// -----------------------------------------------------------------------------
-// CCbsDbImpTopicMessages::InvalidateCacheIfTopic
-// Resets the cache to default values.
-// (other items were commented in a header).
-// -----------------------------------------------------------------------------
-//
-void CCbsDbImpTopicMessages::InvalidateCacheIfTopic(
- const TCbsDbTopicNumber& aNumber )
- {
- // Check the handle and then invalidate
- if ( iCachedTopicNumber == aNumber )
- {
- InvalidateCache();
- }
- }
-
-// -----------------------------------------------------------------------------
-// CCbsDbImpTopicMessages::CreateDefaultTopicMessagesStreamL
-// Creates a default topic messages stream.
-// (other items were commented in a header).
-// -----------------------------------------------------------------------------
-//
-TStreamId CCbsDbImpTopicMessages::CreateDefaultTopicMessagesStreamL(
- CStreamStore& aStore )
- {
- // Create the stream.
- RStoreWriteStream outstream;
- TStreamId id = outstream.CreateLC( aStore ); // on CS
-
- // Write total amount of messages.
- outstream.WriteInt16L( 0 );
-
- // Write total amount of space for messages.
- outstream.WriteInt16L( KDefaultSpaceForMessages );
-
- for ( TInt index( 0 ); index < KDefaultSpaceForMessages; index++ )
- {
- // "Saved"-flag
- CbsStreamHelper::WriteBoolL( outstream, EFalse );
- // Write message stream id.
- outstream << TStreamId( 0 );
- }
-
- outstream.CommitL();
- CleanupStack::PopAndDestroy(); // outstream
-
- return id;
- }
-
-// -----------------------------------------------------------------------------
-// CCbsDbImpTopicMessages::CreateDefaultTopicMessagesStreamL
-// Delete all topics messages.
-// (other items were commented in a header).
-// -----------------------------------------------------------------------------
-//
-void CCbsDbImpTopicMessages::DeleteAllTopicMessagesL(
- CStreamStore& aSavedStore,
- CStreamStore& aUnsavedStore,
- RReadStream& aIn )
- {
- // Read total amount of messages.
- TInt total( aIn.ReadInt16L() );
-
- // Skip space for messages.
- aIn.ReadInt16L();
-
- // Now, delete all streams..
- for ( TInt index( 0 ); index < total; index++ )
- {
-
- TBool isSaved( CbsStreamHelper::ReadBoolL( aIn ) );
- TStreamId id;
-
- // Read stream id.
- aIn >> id;
- CStreamStore& store = isSaved ? aSavedStore : aUnsavedStore;
- store.DeleteL( id );
- }
- }
-
-// -----------------------------------------------------------------------------
-// CCbsDbImpTopicMessages::IsLockedMessagesInTopic
-// Determines whether or not there are any locked messages in
-// the topic.
-// (other items were commented in a header).
-// -----------------------------------------------------------------------------
-//
-TBool CCbsDbImpTopicMessages::IsLockedMessagesInTopic(
- const TCbsDbTopicNumber& aNumber ) const
- {
- TBool result( EFalse );
-
- // Checks whether or not there is a locked message in the topic.
- TInt count( iLockedMessages->Count() );
- for ( TInt index( 0 ); index < count; index++ )
- {
- if ( iTopicList.ExtractTopicNumber(
- iLockedMessages->At( index ) ) == aNumber )
- {
- result = ETrue;
- }
- }
- return result;
- }
-
-// -----------------------------------------------------------------------------
-// CCbsDbImpTopicMessages::IsLockedMessages
-// Determines whether there is at least one locked message.
-// Returns ETrue, if there are any locked messages in the
-// database.
-// (other items were commented in a header).
-// -----------------------------------------------------------------------------
-//
-TBool CCbsDbImpTopicMessages::IsLockedMessages() const
- {
- return ( iLockedMessages->Count() > 0 );
- }
-
-// -----------------------------------------------------------------------------
-// CCbsDbImpTopicMessages::GetMessageCountL
-// Returns the total amount of messages the topic contains.
-// (other items were commented in a header).
-// -----------------------------------------------------------------------------
-//
-void CCbsDbImpTopicMessages::GetMessageCountL(
- const TCbsDbTopicNumber& aNumber,
- TInt& aCount )
- {
- // Load cache.
- LoadCacheL( aNumber );
-
- // and then get the message count.
- aCount = iMessageList->Count();
- }
-
-// -----------------------------------------------------------------------------
-// CCbsDbImpTopicMessages::GetMessageL
-// Returns message information.
-// Returns the message matching the given
-// index value. Leaves if the index is not valid.
-// (other items were commented in a header).
-// -----------------------------------------------------------------------------
-//
-void CCbsDbImpTopicMessages::GetMessageL(
- const TCbsDbTopicNumber& aNumber,
- TInt aIndex,
- TCbsDbMessage& aMessage )
- {
- // Load the cache.
- LoadCacheL( aNumber );
-
- // Check if the index is not valid.
- if ( ( aIndex < 0 ) || ( aIndex >= iMessageList->Count() ) )
- {
- User::Leave( KErrNotFound );
- }
-
- // Load the message.
- LoadMessageL( aIndex, aMessage );
- }
-
-// -----------------------------------------------------------------------------
-// CCbsDbImpTopicMessages::FindMessageByHandleL
-// Finds the message for given handle and returns it.
-// Returns the message matching the given
-// index value.
-// (other items were commented in a header).
-// -----------------------------------------------------------------------------
-//
-void CCbsDbImpTopicMessages::FindMessageByHandleL(
- const TCbsDbMessageHandle& aHandle,
- TCbsDbMessage& aMessage )
- {
- // Load cache
- LoadCacheL( iTopicList.ExtractTopicNumber( aHandle ) );
-
- // Load message
- LoadMessageL( FindMessagePositionByHandleL( aHandle ), aMessage );
- }
-
-// -----------------------------------------------------------------------------
-// CCbsDbImpTopicMessages::GetMessageContentsL
-// Returns the contents of a message.
-// Stores the contents of the message to the buffer aContents.
-// If aContents is too small to contain the whole message
-// body, the message body is truncated.
-// (other items were commented in a header).
-// -----------------------------------------------------------------------------
-//
-void CCbsDbImpTopicMessages::GetMessageContentsL(
- const TCbsDbMessageHandle& aHandle,
- TPtr& aContents,
- TUint aSize )
- {
- LoadCacheL( iTopicList.ExtractTopicNumber( aHandle ) );
-
- TInt position( FindMessagePositionByHandleL( aHandle ) );
-
- TCbsDbMessage message;
- LoadMessageL( position, message );
-
- LoadMessageContentsL( iMessageList->At( position ).iContentsId,
- aContents, message.iPermanent, aSize );
- }
-
-// -----------------------------------------------------------------------------
-// CCbsDbImpTopicMessages::DeleteMessageL
-// Deletes a message. Leaves if the message is protected
-// (other items were commented in a header).
-// -----------------------------------------------------------------------------
-//
-void CCbsDbImpTopicMessages::DeleteMessageL(
- const TCbsDbMessageHandle& aHandle,
- const CCbsRecEtel& aReceiver )
- {
- // Get the topic handle.
- LoadCacheL( iTopicList.ExtractTopicNumber( aHandle ) );
-
- // Check if the message is locked.
- if ( IsMessageLocked( aHandle ) )
- {
- // Yes, leave.
- User::Leave( KErrAccessDenied );
- }
- else
- {
- // Otherwise, delete.
- TRAPD( error, DoDeleteMessageL(
- FindMessagePositionByHandleL( aHandle ) ) );
-
- if ( error != KErrNone )
- {
- // Failed.
- RevertFileOperationL( error );
- }
- else
- {
- // Update the soft notification dialog, if topic is hotmarked
- UpdateSoftNotificationL( aHandle, aReceiver );
- }
- }
-
- iTopicList.NotifyTopicModifiedL(
- iTopicList.ExtractTopicNumber( aHandle ) );
- }
-
-// -----------------------------------------------------------------------------
-// CCbsDbImpTopicMessages::AddMessageL
-// Creates a new message to the topic.
-// Stores a handle to the message in aHandle.
-// FFS critical level check is made prior to operation.
-// (other items were commented in a header).
-// -----------------------------------------------------------------------------
-//
-void CCbsDbImpTopicMessages::AddMessageL(
- const TCbsDbTopicNumber& aNumber,
- TCbsDbMessage& aMessage,
- const TPtrC& aContents )
- {
- CBSLOGSTRING("CBSSERVER: >>> CCbsDbImpTopicMessages::AddMessageL()");
-
- LoadCacheL( aNumber );
-
- aMessage.iLength = aContents.Length();
- CBSLOGSTRING2("CBSSERVER: CCbsDbImpTopicMessages::AddMessageL(): Content length: %d.", aMessage.iLength );
-
- // Generate a new message handle.
- aMessage.iHandle = GenerateNewMessageHandle( aNumber );
-
- // Make sure that the message is not inserted as permanent
- aMessage.iPermanent = EFalse;
-
- TRAPD( error, DoAddMessageL( aMessage, aContents ) );
- if ( error != KErrNone )
- {
- CBSLOGSTRING2("CBSSERVER: CCbsDbImpTopicMessages::AddMessageL(): DoAddMessageL() failed, error: %d.", error );
-
- // Failed.
- RevertFileOperationL( error );
-
- CBSLOGSTRING("CBSSERVER: CCbsDbImpTopicMessages::AddMessageL(): RevertFileOperationL() finished OK." );
- }
-
- CBSLOGSTRING("CBSSERVER: <<< CCbsDbImpTopicMessages::AddMessageL()");
- }
-
-// -----------------------------------------------------------------------------
-// CCbsDbImpTopicMessages::SaveMessageL
-// Saves a message.
-// This operation is called "keeping" in the UI.
-// The CBS server has a global limit for saved
-// messages. The function leaves, if this is exceeded.
-// A saved message has it's permanent-flag raised.
-// FFS critical level check is made prior to the operation.
-// (other items were commented in a header).
-// -----------------------------------------------------------------------------
-//
-void CCbsDbImpTopicMessages::SaveMessageL(
- const TCbsDbMessageHandle& aHandle,
- const CCbsRecEtel& aReceiver )
- {
- // Load cache.
- TCbsTopicNumber topicNumber( iTopicList.ExtractTopicNumber( aHandle ) );
- LoadCacheL( topicNumber );
-
- // Now find message by handle.
- TInt position( FindMessagePositionByHandleL( aHandle ) );
-
- TCbsDbMessage message;
- LoadMessageL( position, message );
- TStreamId contentsId( iMessageList->At( position ).iContentsId );
-
- // This function should not be called if the message is already permanent.
- if ( message.iPermanent )
- {
- User::Leave( KErrAlreadyExists );
- }
-
- // Check that the limit for maximum saved messages/topic is not exceeded.
- TCbsDbTopic topic;
- iTopicList.FindTopicByNumberL( topicNumber, topic );
- if ( iTopicList.TotalSavedMessages() >= KCbsDbMaxSavedMessages )
- {
- User::Leave( KErrOverflow );
- }
-
- // FFS critical level check (header is 16 bytes, message coded in Unicode)
- CbsUtils::FFSCriticalLevelCheckL( KCbMessageHeaderSize +
- 2 * message.iLength, iFs );
-
- // Create a temporary buffer for message body and load the contents into
- // the buffer.
- HBufC* buffer = HBufC::NewLC( message.iLength ); // on CS
- TPtr contentPtr( buffer->Des() );
- LoadMessageContentsL( contentsId, contentPtr, EFalse, message.iLength );
-
- // Delete message's previous header and body streams.
- TCbsDbImpTopicMessagesCacheItem item( iMessageList->At( position ) );
-
- TRAPD( result, DoSaveMessageL( message, item, contentPtr, position ) );
- CleanupStack::PopAndDestroy( buffer );
- if ( result != KErrNone )
- {
- RevertFileOperationL( result );
- }
- else
- {
- iTopicList.NotifyTopicModifiedL(
- iTopicList.ExtractTopicNumber( aHandle ) );
-
- // Update the soft notification dialog, if topic is hotmarked
- UpdateSoftNotificationL( aHandle, aReceiver );
- }
- }
-
-// -----------------------------------------------------------------------------
-// CCbsDbImpTopicMessages::DoSaveMessageL
-// Saves a message.
-// (other items were commented in a header).
-// -----------------------------------------------------------------------------
-//
-void CCbsDbImpTopicMessages::DoSaveMessageL(
- TCbsDbMessage& aMessage,
- const TCbsDbImpTopicMessagesCacheItem& aItem,
- const TDesC& aContentPtr,
- TInt aPosition )
- {
- CFileStore* store = iTopicList.UnsavedMessagesStore();
- store->Delete( aItem.iId );
- store->Delete( aItem.iContentsId );
-
- TBool needToUpdateReadCounter( EFalse );
- aMessage.iPermanent = ETrue;
- if ( !aMessage.iRead )
- {
- needToUpdateReadCounter = ETrue;
- aMessage.iRead = ETrue;
- }
-
- // Create new streams for message header and body.
- TStreamId contentsStream( CreateMessageContentsStreamL(
- *iTopicList.TopicStoreL(), aContentPtr ) );
- TStreamId messageStream( CreateMessageStreamL(
- *iTopicList.TopicStoreL(), aMessage, contentsStream ) );
-
- // Update message's cache item information.
- TCbsDbImpTopicMessagesCacheItem& item = iMessageList->At( aPosition );
- item.iContentsId = contentsStream;
- item.iId = messageStream;
- item.iIsSaved = ETrue;
- item.iMessage = aMessage;
-
- // Update topic messages stream; the cache item is saved into the stream.
- UpdateTopicMessagesStreamL( EFalse );
-
- iTopicList.InformMessageSavedL( aMessage.iHandle );
- if ( needToUpdateReadCounter )
- {
- iTopicList.InformUnreadMessageReadL( aMessage.iHandle );
- }
-
- // Commit changes to both files.
- iTopicList.CommitFilesL();
- }
-
-// -----------------------------------------------------------------------------
-// CCbsDbImpTopicMessages::ReadMessageL
-// Marks the message read
-// (other items were commented in a header).
-// -----------------------------------------------------------------------------
-//
-void CCbsDbImpTopicMessages::ReadMessageL(
- const TCbsDbMessageHandle& aHandle,
- const CCbsRecEtel& aReceiver )
- {
- //Checked that there is space for writing data on FFS.
- CbsUtils::FFSCriticalLevelCheckL( KReadMessageSize, iFs );
-
- // Load cache.
- TCbsDbTopicNumber topicNum( iTopicList.ExtractTopicNumber( aHandle ) );
- LoadCacheL( topicNum );
-
- // Now find message by handle.
- TInt position( FindMessagePositionByHandleL( aHandle ) );
-
- TCbsDbMessage message;
- LoadMessageL( position, message );
- TStreamId contentsId( iMessageList->At( position ).iContentsId );
- TStreamId id( iMessageList->At( position ).iId );
-
- // Check if the message is already read, then there is nothing more to do.
- if ( !message.iRead )
- {
- message.iRead = ETrue;
-
- TRAPD( error, DoReadMessageL( id, message, contentsId ) );
- if ( error == KErrNone )
- {
- iMessageList->At( position ).iMessage = message;
-
- iTopicList.NotifyTopicModifiedL(
- iTopicList.ExtractTopicNumber( aHandle ) );
-
- // Update the soft notification dialog, if topic is hotmarked
- UpdateSoftNotificationL( aHandle, aReceiver );
- }
- else
- {
- RevertFileOperationL( error );
- }
- }
- }
-
-// -----------------------------------------------------------------------------
-// CCbsDbImpTopicMessages::UpdateHandlesOfTopicMessagesL
-// Updates handles of messages in the topic with the number given in
-// aOldTopicNumber to match new topic number.
-// Traverses through the given topic processing
-// each message stream encountered. Since the topic number is
-// the primary key and previous message handles can be assumed
-// to be unique, updating the high word of the handle to
-// match the new topic number is adequate.
-// (other items were commented in a header).
-// -----------------------------------------------------------------------------
-//
-void CCbsDbImpTopicMessages::UpdateHandlesOfTopicMessagesL(
- const TCbsDbTopicNumber& aOldTopicNumber,
- const TCbsDbTopicNumber& aNewTopicNumber )
- {
- LoadCacheL( aOldTopicNumber );
-
- TInt msgs( iMessageList->Count() );
-
- for ( TInt i( 0 ); i < msgs; i++ )
- {
- // Fetch message at this position
- TCbsDbMessage message;
- LoadMessageL( i, message );
- TStreamId contentsStreamId( iMessageList->At( i ).iContentsId );
- TStreamId messageStreamId( iMessageList->At( i ).iId );
-
- // Insert new topic number as the high word of the handle
- message.iHandle = ( aNewTopicNumber << 16 ) |
- ( message.iHandle & 0xFFFF );
- DoUpdateMessageL( messageStreamId, message, contentsStreamId );
- }
- }
-
-// -----------------------------------------------------------------------------
-// CCbsDbImpTopicMessages::LockMessageL
-// Unlocks one message and then locks another message.
-// Message that is locked can not be removed. Topic that
-// contains a locked message can not be removed.
-// Note that locking status is not persistent in the sense that
-// when the power is switched off and turned on, no messages
-// are automatically locked.
-// (other items were commented in a header).
-// -----------------------------------------------------------------------------
-//
-void CCbsDbImpTopicMessages::LockMessageL(
- const TCbsDbMessageHandle& aUnlock,
- const TCbsDbMessageHandle& aLock )
- {
- // Check if the message exists: leave if not found, ignore return value
- if ( aLock != 0 )
- {
- TCbsDbMessage message;
- TInt position( FindMessagePositionByHandleL( aLock ) );
- LoadMessageL( position, message );
- }
-
- TBool unlockNull( ETrue );
-
- if ( aUnlock != 0 )
- {
- DeleteFromLocked( aUnlock );
- unlockNull = EFalse;
- }
-
- if ( aLock != 0 )
- {
- InsertToLockedL( aLock ) ;
- }
-
- if ( unlockNull == EFalse )
- {
- LoadCacheL( iTopicList.ExtractTopicNumber( aUnlock ) );
- }
- }
-
-// -----------------------------------------------------------------------------
-// CCbsDbImpTopicMessages::GetNextAndPrevMsgHandleL
-// Returns the handles of the next and previous message
-// when given a current message.
-// (other items were commented in a header).
-// -----------------------------------------------------------------------------
-//
-void CCbsDbImpTopicMessages::GetNextAndPrevMsgHandleL(
- const TCbsDbMessageHandle& aCurrentMsg,
- TCbsDbMessageHandle& aNextMsg,
- TCbsDbMessageHandle& aPrevMsg,
- TInt& aPosition)
- {
- LoadCacheL( iTopicList.ExtractTopicNumber( aCurrentMsg ) );
-
- // Load the current message
- TInt index( FindMessagePositionByHandleL( aCurrentMsg ) );
-
- // Reset position indications
- aPosition = 0;
-
- // Retrieve position indications and message handles
- if ( index == 0 )
- {
- aPosition |= ECbsHead;
- }
- else
- {
- TCbsDbMessage prevMessage;
- LoadMessageL( index - 1, prevMessage );
- aPrevMsg = prevMessage.iHandle;
- }
-
- // If index points to the last element of iMessageList,
- // raise flag ECbsTail.
- if ( index == iMessageList->Count()-1 )
- {
- aPosition |= ECbsTail;
- }
- else
- {
- TCbsDbMessage nextMessage;
- LoadMessageL( index+1, nextMessage );
- aNextMsg = nextMessage.iHandle;
- }
- }
-
-// -----------------------------------------------------------------------------
-// CCbsDbImpTopicMessages::DoAddMessageL
-// Inserts a message into the database.
-// (other items were commented in a header).
-// -----------------------------------------------------------------------------
-//
-void CCbsDbImpTopicMessages::DoAddMessageL(
- TCbsDbMessage& aMessage,
- const TDesC& aContents )
- {
- // Cache is assumed to be loaded. Message is assumed not to
- // already exist in the DB.
- CFileStore* store = aMessage.iPermanent ?
- iTopicList.TopicStoreL() : iTopicList.UnsavedMessagesStore();
-
- if ( aMessage.iPermanent )
- {
- // About to write to FFS: make critical level check.
- // Message is in Unicode characters, so its size
- // is double the length.
- CbsUtils::FFSCriticalLevelCheckL( KCbMessageHeaderSize +
- 2 * aMessage.iLength, iFs );
- }
- else
- {
- CbsUtils::VolumeCriticalLevelCheckL(
- iTopicList.UnsavedMessagesFilename(),
- KCbMessageHeaderSize + 2 * aMessage.iLength, iFs );
- }
-
- // Create stream for contents.
- TStreamId contentsStream( CreateMessageContentsStreamL(
- *store, aContents ) );
-
- // Now we have to find the position to which the message should be
- // inserted.
- TInt positionToBeInserted( -1 );
-
- TTime messageTime( aMessage.iDateTime );
- TInt index( 0 );
-
- // Go through all messages in topic and find the position.
- TInt count( iMessageList->Count() );
- for ( ; index < count && positionToBeInserted == -1; index++ )
- {
- TCbsDbMessage message;
- LoadMessageL( index, message );
-
- TTime tmp( message.iDateTime );
-
- if ( tmp <= messageTime )
- {
- positionToBeInserted = index;
- }
- }
-
- // If we looped through, append
- if ( positionToBeInserted == -1 )
- {
- positionToBeInserted = index;
- }
-
- // Create message stream.
- TStreamId messageStream( CreateMessageStreamL( *store,
- aMessage, contentsStream ) );
-
- // Add to internal cache.
- TCbsDbImpTopicMessagesCacheItem item;
-
- item.iId = messageStream;
- item.iIsMessage = EFalse;
- item.iIsSaved = aMessage.iPermanent;
-
- iMessageList->InsertL( positionToBeInserted, item );
-
- // Check if message should be deleted.
- DeleteReceivedIfNecessaryL();
-
- // Update topic messages stream.
- UpdateTopicMessagesStreamL( EFalse );
-
- // Update counters.
- iTopicList.InformNewMessageReceivedL( aMessage.iHandle );
-
- // Commit changes to both stores.
- iTopicList.CommitFilesL();
-
- // Inform observers. Done after commit to make sure there's
- // a message to inform of.
- iTopicList.NotifyNewMessageArrivedL( aMessage.iHandle );
- }
-
-// -----------------------------------------------------------------------------
-// CCbsDbImpTopicMessages::DoDeleteMessageL
-// Deletes a message from the database.
-// (other items were commented in a header).
-// -----------------------------------------------------------------------------
-//
-void CCbsDbImpTopicMessages::DoDeleteMessageL(
- TInt aPosition )
- {
- TCbsDbMessage message;
- LoadMessageL( aPosition, message );
-
- // Delete the message, if it is possible.
- DeleteMessageByPositionL( aPosition );
- DeleteReceivedIfNecessaryL();
- UpdateTopicMessagesStreamL( ETrue );
-
- // Inform the topic list about deletion.
- iTopicList.InformMessageDeletedL( message.iHandle,
- message.iPermanent, message.iRead );
-
- iTopicList.CommitFilesL();
- }
-
-// -----------------------------------------------------------------------------
-// CCbsDbImpTopicMessages::DoUpdateMessageL
-// Updates the information for a message.
-// (other items were commented in a header).
-// -----------------------------------------------------------------------------
-//
-void CCbsDbImpTopicMessages::DoUpdateMessageL(
- const TStreamId& aId,
- const TCbsDbMessage& aMessage,
- const TStreamId& aContentsId ) const
- {
- // Update the stream contents.
- CFileStore* store = aMessage.iPermanent ?
- iTopicList.TopicStoreL() : iTopicList.UnsavedMessagesStore();
-
- RStoreWriteStream outstream;
- outstream.ReplaceLC( *store, aId ); // on CS
-
- WriteMessageInformationL( outstream, aMessage, aContentsId );
-
- outstream.CommitL();
- CleanupStack::PopAndDestroy(); // outstream
- }
-
-// -----------------------------------------------------------------------------
-// CCbsDbImpTopicMessages::DoReadMessageL
-// Marks a message read by updating it in the database.
-// (other items were commented in a header).
-// -----------------------------------------------------------------------------
-//
-void CCbsDbImpTopicMessages::DoReadMessageL(
- const TStreamId& aId,
- const TCbsDbMessage& aMessage,
- const TStreamId& aContentsId )
- {
- DoUpdateMessageL( aId, aMessage, aContentsId );
- iTopicList.InformUnreadMessageReadL( aMessage.iHandle );
- iTopicList.CommitFilesL();
- }
-
-// -----------------------------------------------------------------------------
-// CCbsDbImpTopicMessages::DoDeleteL
-// Deletes messages that are not supposed to be in the topic.
-// Because of message locking it is possible that there are more
-// received messages than there should be. This method tries to
-// delete this kind of message.
-// (other items were commented in a header).
-// -----------------------------------------------------------------------------
-//
-void CCbsDbImpTopicMessages::DoDeleteL()
- {
- CBSLOGSTRING("CBSSERVER: >>> CCbsDbImpTopicMessages::DoDeleteL()");
-
- // Delete temporary messages and update topic messages stream.
- if ( DeleteReceivedIfNecessaryL() )
- {
- UpdateTopicMessagesStreamL( ETrue );
- }
- iTopicList.CommitFilesL();
-
- CBSLOGSTRING("CBSSERVER: <<< CCbsDbImpTopicMessages::DoDeleteL()");
- }
-
-// -----------------------------------------------------------------------------
-// CCbsDbImpTopicMessages::FindMessageByKeyL
-// Returns a handle to a message with the given key.
-// (other items were commented in a header).
-// -----------------------------------------------------------------------------
-//
-TInt CCbsDbImpTopicMessages::FindMessageByKeyL(
- TCbsDbTopicNumber aNumber,
- TCbsDbMessageKey aKey,
- TCbsDbMessage& aMessage )
- {
- TCbsDbMessage message;
- TInt count;
- TBool result( KErrNotFound );
-
- // Find a message even if the update numbers don't match
- aKey &= 0xfff0;
-
- // Try to find a message with the same key in the topic.
- LoadCacheL( aNumber );
- GetMessageCountL( aNumber, count );
-
- for ( TInt index( 0 ); ( index < count ) && ( result != KErrNone ); index++ )
- {
- LoadMessageL( index, message );
-
- if ( (message.iKey & 0xfff0) == aKey )
- {
- aMessage = message;
- result = KErrNone; // message was found
- }
- }
- return result;
- }
-
-// -----------------------------------------------------------------------------
-// CCbsDbImpTopicMessages::FindMessagePositionByHandleL
-// Returns the position of a message with the given handle.
-// (other items were commented in a header).
-// -----------------------------------------------------------------------------
-//
-TInt CCbsDbImpTopicMessages::FindMessagePositionByHandleL(
- const TCbsDbMessageHandle& aHandle )
- {
- // Load the cache.
- LoadCacheL( iTopicList.ExtractTopicNumber( aHandle ) );
-
- // Now, find the message
- TInt count( iMessageList->Count() );
-
- TCbsDbMessage message;
- TBool found( EFalse );
-
- // Go through messages.
- TInt index( 0 );
- for ( ; ( index < count ) && !found; )
- {
- // Load the message.
- LoadMessageL( index, message );
-
- // Check if it is this one.
- if ( message.iHandle == aHandle )
- {
- found = ETrue;
- }
- else
- {
- index++;
- }
- }
-
- if ( !found )
- {
- User::Leave( KErrNotFound );
- }
-
- return index;
- }
-
-// -----------------------------------------------------------------------------
-// CCbsDbImpTopicMessages::LoadCacheL
-// Loads the cache, if it is not already loaded with this topic information.
-// The method does not load any message information to the cache
-// - only what is really necessary.
-// (other items were commented in a header).
-// -----------------------------------------------------------------------------
-//
-void CCbsDbImpTopicMessages::LoadCacheL(
- const TCbsDbTopicNumber& aNumber )
- {
- CBSLOGSTRING2("CBSSERVER: >>> CCbsDbImpTopicMessages::LoadCacheL(), topic number: %d.", aNumber );
-
- // Check if the cache is valid. If not, load it.
- if ( !( iCacheValid && ( iCachedTopicNumber == aNumber ) ) )
- {
- CBSLOGSTRING("CBSSERVER: CCbsDbImpTopicMessages::LoadCacheL(): Calling InvalidateCache()...");
- // Invalidate the old cache, if it is necessary.
- InvalidateCache();
- CBSLOGSTRING("CBSSERVER: CCbsDbImpTopicMessages::LoadCacheL(): InvalidateCache() called OK.");
-
- // Load message queue ids.
- TStreamId id;
- iTopicList.GetTopicMessagesIdL( aNumber, id );
-
- ReadTopicMessagesCacheItemsL( *iTopicList.TopicStoreL(),
- id, *iMessageList, iSpaceForMessages );
-
- // Cache is valid.
- iCachedTopicNumber = aNumber;
- iCacheValid = ETrue;
-
- // Check if it there are more topics than there should be.
- TCbsDbTopic topic;
- iTopicList.FindTopicByNumberL( aNumber, topic );
- if ( ( iMessageList->Count() - topic.iSavedMessages ) >
- KCbsDbMaxReceivedMessages )
- {
- TRAPD( error, DoDeleteL() );
- CBSLOGSTRING2("CBSSERVER: CCbsDbImpTopicMessages::LoadCacheL(): DoDeleteL() finished with %d.", error );
-
- if ( error != KErrNone )
- {
- RevertFileOperationL( error );
- }
- }
- }
- CBSLOGSTRING("CBSSERVER: <<< CCbsDbImpTopicMessages::LoadCacheL()");
- }
-
-// -----------------------------------------------------------------------------
-// CCbsDbImpTopicMessages::LoadMessageL
-// Loads the message header to the cache.
-// Note that it is assumed that the index is in proper range and
-// the cache is already loaded.
-// (other items were commented in a header).
-// -----------------------------------------------------------------------------
-//
-void CCbsDbImpTopicMessages::LoadMessageL(
- TInt aIndex,
- TCbsDbMessage& aMessage )
- {
- CBSLOGSTRING("CBSSERVER: >>> CCbsDbImpTopicMessages::LoadMessageL()");
-
- // Check that the aIndex is in proper range and.
- // that the cache is valid (just for sure).
- if ( aIndex < 0 || aIndex >= iMessageList->Count() ||
- !iCacheValid )
- {
- CBSLOGSTRING("CBSSERVER: CCbsDbImpTopicMessages::LoadMessageL(): Leaving with KErrNotFound...");
- User::Leave( KErrNotFound );
- }
-
- // Check if the message information is already loaded.
- if ( iMessageList->At( aIndex ).iIsMessage )
- {
- // Yes, just make a fast copy.
- aMessage = iMessageList->At( aIndex ).iMessage;
- CBSLOGSTRING("CBSSERVER: CCbsDbImpTopicMessages::LoadMessageL(): Msg already loaded, fast copy made.");
- }
- else
- {
- TStreamId id( TStreamId( 0 ) );
- // Choose the file store: saved messages are stored elsewhere
- // than other messages.
- CFileStore* store = iMessageList->At( aIndex ).iIsSaved ?
- iTopicList.TopicStoreL() :
- iTopicList.UnsavedMessagesStore();
- CBSLOGSTRING("CBSSERVER: CCbsDbImpTopicMessages::LoadMessageL(): Store created.");
-
- // Then read the message. If the message stream cannot be
- // found, delete the reference to the message
- TRAPD( error, ReadMessageInformationL( *store,
- iMessageList->At( aIndex ).iId, aMessage, id ) );
-
- CBSLOGSTRING2("CBSSERVER: CCbsDbImpTopicMessages::LoadMessageL(): ReadMessageInformationL() finished with %d.", error );
-
- if( error == KErrNotFound )
- {
- DeleteMessageByPositionL( aIndex );
- UpdateTopicMessagesStreamL( ETrue );
- iTopicList.CommitFilesL();
- }
-
- CBSLOGSTRING2("CBSSERVER: CCbsDbImpTopicMessages::LoadMessageL(): Leaving if error code < 0: error %d...", error );
- User::LeaveIfError( error );
-
- // And copy to the internal cache.
- iMessageList->At( aIndex ).iIsMessage = ETrue;
- iMessageList->At( aIndex ).iContentsId = id;
- iMessageList->At( aIndex ).iMessage = aMessage;
- }
- CBSLOGSTRING("CBSSERVER: <<< CCbsDbImpTopicMessages::LoadMessageL()");
- }
-
-// -----------------------------------------------------------------------------
-// CCbsDbImpTopicMessages::LoadMessageContentsL
-// Loads message contents (as much as it fits).
-// Restores the contents of a message
-// by reading a stream specified in parameter aContentsId.
-// Save status of message is required because saved and unsaved
-// messages are stored on separate files.
-// (other items were commented in a header).
-// -----------------------------------------------------------------------------
-//
-void CCbsDbImpTopicMessages::LoadMessageContentsL(
- const TStreamId& aContentsId,
- TPtr& aContents,
- TBool aIsSaved,
- TUint aSize ) const
- {
- CFileStore* store = aIsSaved ?
- iTopicList.TopicStoreL() :
- iTopicList.UnsavedMessagesStore();
-
- // Read data to the buffer.
- RStoreReadStream instream;
- instream.OpenLC( *store, aContentsId ); // on CS
-
- // Read the data into a temporary buffer first.
- // Then copy to the aContents descriptor only
- // as much as it can take.
- TUint length( instream.ReadInt16L() );
- if ( length > KCbsMaxCharsInMessage )
- {
- User::Leave( KErrCorrupt );
- }
-
- HBufC* buf = HBufC::NewL( instream, length );
- if ( length > aSize )
- {
- length = aSize;
- }
-
- aContents.Copy( buf->Ptr(), length );
- delete buf;
-
- CleanupStack::PopAndDestroy(); // instream
- }
-
-// -----------------------------------------------------------------------------
-// CCbsDbImpTopicMessages::GenerateNewMessageHandle
-// Generates a new, unique handle for a message.
-// The generation uses topic number as
-// basis and then increments the handle value until an unique
-// handle is found.
-// (other items were commented in a header).
-// -----------------------------------------------------------------------------
-//
-TCbsDbMessageHandle CCbsDbImpTopicMessages::GenerateNewMessageHandle(
- const TCbsDbTopicNumber& aNumber )
- {
- // Start with a reasonable seed. We'll try the number
- // of messages in topic, plus one.
- TUint16 handleLow( TUint16( iMessageList->Count() + 1 ) );
- TCbsDbMessageHandle handle( 1 );
- TInt error( KErrNone );
-
- while ( error == KErrNone )
- {
- handleLow++;
- if ( handleLow == 0 )
- {
- handleLow++;
- }
-
- // Generate a new message handle.
- handle = iTopicList.GenerateMessageHandle( aNumber,
- handleLow );
-
- TRAP( error, ( FindMessagePositionByHandleL( handle ) ) );
- }
- return handle;
- }
-
-// -----------------------------------------------------------------------------
-// CCbsDbImpTopicMessages::DeleteReceivedIfNecessaryL
-// Checks that if there are too many received messages in the internal cache,
-// then they will be deleted if they are not locked.
-// Note: Count() is changed in for-loop.
-// (other items were commented in a header).
-// -----------------------------------------------------------------------------
-//
-TBool CCbsDbImpTopicMessages::DeleteReceivedIfNecessaryL()
- {
- CBSLOGSTRING("CBSSERVER: >>> CCbsDbImpTopicMessages::DeleteReceivedIfNecessaryL()");
-
- // So check if there are too many received messages in the topic.
- // Thus delete if message is not locked.
-
- __ASSERT_DEBUG( iCacheValid, CbsServerPanic( ECbsCacheNotValid ) );
-
- TInt totalReceived( 0 );
- TCbsDbMessage message;
- TBool result( EFalse );
- TInt index( 0 );
-
- for ( index = 0; index < iMessageList->Count(); index++ )
- {
- LoadMessageL( index, message );
-
- // Count the amount of received messages
- if ( !message.iPermanent )
- {
- totalReceived++;
-
- // If there are too many, then check that it can be deleted.
- if ( totalReceived > KCbsDbMaxReceivedMessages &&
- !IsMessageLocked( message.iHandle ) )
- {
- // Delete the message.
- DeleteMessageByPositionL( index );
- iTopicList.InformMessageDeletedL
- ( message.iHandle,
- message.iPermanent,
- message.iRead );
- result = ETrue;
-
- // They are always deleted from internal cache
- index--;
- totalReceived--;
- }
- }
- }
-
- CBSLOGSTRING2("CBSSERVER: <<< CCbsDbImpTopicMessages::DeleteReceivedIfNecessaryL(), returning %d.", result );
- return result;
- }
-
-// -----------------------------------------------------------------------------
-// CCbsDbImpTopicMessages::DeleteMessageByPositionL
-// Deletes message by its position in the internal cache.
-// Note that after the call the internal cache won't contain
-// the item.
-// (other items were commented in a header).
-// -----------------------------------------------------------------------------
-//
-void CCbsDbImpTopicMessages::DeleteMessageByPositionL(
- TInt aIndex )
- {
- CBSLOGSTRING("CBSSERVER: >>> CCbsDbImpTopicMessages::DeleteMessageByPositionL()");
-
- // Delete from cache and from file.
- __ASSERT_DEBUG( iCacheValid, CbsServerPanic( ECbsCacheNotValid ) );
-
- TCbsDbImpTopicMessagesCacheItem item( iMessageList->At( aIndex ) );
-
- // Determine the file where the message is stored.
- CFileStore* store = item.iIsSaved ? iTopicList.TopicStoreL() :
- iTopicList.UnsavedMessagesStore();
-
- iMessageList->Delete( aIndex );
-
- store->Delete( item.iId );
- store->Delete( item.iContentsId );
-
- CBSLOGSTRING("CBSSERVER: <<< CCbsDbImpTopicMessages::DeleteMessageByPositionL()");
- }
-
-// -----------------------------------------------------------------------------
-// CCbsDbImpTopicMessages::IsMessageLocked
-// Determines whether or not the message is locked.
-// (other items were commented in a header).
-// -----------------------------------------------------------------------------
-//
-TBool CCbsDbImpTopicMessages::IsMessageLocked(
- const TCbsDbMessageHandle& aHandle ) const
- {
- // Find out if the message is locked.
- TBool found( EFalse );
- TInt count( iLockedMessages->Count() );
- for ( TInt index( 0 ); ( index < count ) && !found; index++ )
- {
- if ( iLockedMessages->At( index ) == aHandle )
- {
- found = ETrue;
- }
- }
-
- return found;
- }
-
-// -----------------------------------------------------------------------------
-// CCbsDbImpTopicMessages::DeleteFromLocked
-// Deletes from the locked messages.
-// (other items were commented in a header).
-// -----------------------------------------------------------------------------
-//
-void CCbsDbImpTopicMessages::DeleteFromLocked(
- const TCbsDbMessageHandle& aHandle )
- {
- TBool deleted( EFalse );
- TInt count( iLockedMessages->Count() );
-
- for ( TInt index( 0 ); ( index < count ) && !deleted; index++ )
- {
- if ( iLockedMessages->At( index ) == aHandle )
- {
- iLockedMessages->Delete( index );
- deleted = ETrue;
- }
- }
- }
-
-// -----------------------------------------------------------------------------
-// CCbsDbImpTopicMessages::InsertToLockedL
-// Adds a handle to the locked messages.
-// (other items were commented in a header).
-// -----------------------------------------------------------------------------
-//
-void CCbsDbImpTopicMessages::InsertToLockedL(
- const TCbsDbMessageHandle& aHandle )
- {
- // Just append to the end.
- iLockedMessages->AppendL( aHandle );
- }
-
-// -----------------------------------------------------------------------------
-// CCbsDbImpTopicMessages::UpdateTopicMessagesStreamL
-// Updates topic messages stream from the internal cache.
-// (other items were commented in a header).
-// -----------------------------------------------------------------------------
-//
-void CCbsDbImpTopicMessages::UpdateTopicMessagesStreamL(
- TBool aDeleting )
- {
- CBSLOGSTRING("CBSSERVER: >>> CCbsDbImpTopicMessages::UpdateTopicMessagesStreamL()");
-
- __ASSERT_DEBUG( iCacheValid, CbsServerPanic( ECbsCacheNotValid ) );
-
- TInt neededSpace( KMessageRootStreamSize +
- iMessageList->Count() * KMessageEntrySize );
-
- RSharedDataClient sharedData;
- // About to write to FFS: make critical level check
- if ( aDeleting )
- {
- User::LeaveIfError( sharedData.Connect() );
- sharedData.RequestFreeDiskSpaceLC( neededSpace ); // on CS
- }
- else
- {
- CbsUtils::FFSCriticalLevelCheckL( neededSpace, iFs );
- }
-
- // Now, first check if the information fits well to the current stream.
- if ( iSpaceForMessages >= iMessageList->Count() )
- {
- CBSLOGSTRING("CBSSERVER: CCbsDbImpTopicMessages::UpdateTopicMessagesStreamL(): (3)");
-
- // Write data to the old stream.
- TStreamId id;
- iTopicList.GetTopicMessagesIdL( iCachedTopicNumber, id );
- CBSLOGSTRING("CBSSERVER: CCbsDbImpTopicMessages::UpdateTopicMessagesStreamL(): (4)");
-
- // Replace the existing stream.
- RStoreWriteStream outstream;
- outstream.ReplaceLC( *iTopicList.TopicStoreL(), id ); // on CS
- CBSLOGSTRING("CBSSERVER: CCbsDbImpTopicMessages::UpdateTopicMessagesStreamL(): (5)");
-
- WriteTopicMessagesStreamL( outstream );
- CBSLOGSTRING("CBSSERVER: CCbsDbImpTopicMessages::UpdateTopicMessagesStreamL(): (6)");
-
- outstream.CommitL();
- CleanupStack::PopAndDestroy(); // outstream
- }
- else
- {
- CBSLOGSTRING("CBSSERVER: CCbsDbImpTopicMessages::UpdateTopicMessagesStreamL(): (7)");
- // Calculate the amount of space for messages.
- if ( iSpaceForMessages == 0 )
- {
- // Zero is not very good, lets put it greater.
- iSpaceForMessages = KDefaultSpaceForMessages;
- }
-
- // But no need for extra messages.
- iSpaceForMessages = 2 * iSpaceForMessages;
- if ( iSpaceForMessages >
- ( KCbsDbMaxReceivedMessages + KCbsDbMaxSavedMessages ) )
- {
- iSpaceForMessages =
- KCbsDbMaxReceivedMessages + KCbsDbMaxSavedMessages;
- }
- if ( iMessageList->Count() > iSpaceForMessages )
- {
- iSpaceForMessages = iMessageList->Count();
- }
-
- // And finally write the data to stream.
- RStoreWriteStream outstream;
- TStreamId id = outstream.CreateLC( *iTopicList.TopicStoreL() );// on CS
- CBSLOGSTRING("CBSSERVER: CCbsDbImpTopicMessages::UpdateTopicMessagesStreamL(): (8)");
-
- WriteTopicMessagesStreamL( outstream );
- CBSLOGSTRING("CBSSERVER: CCbsDbImpTopicMessages::UpdateTopicMessagesStreamL(): (9)");
-
- outstream.CommitL();
- CleanupStack::PopAndDestroy(); // outstream
-
- // And then update topic messages stream. It will also delete
- // the old stream.
- iTopicList.UpdateTopicMessagesIdL( iCachedTopicNumber, id );
- CBSLOGSTRING("CBSSERVER: CCbsDbImpTopicMessages::UpdateTopicMessagesStreamL(): (10)");
- }
-
- // Free the reserved space
- if ( aDeleting )
- {
- CBSLOGSTRING("CBSSERVER: CCbsDbImpTopicMessages::UpdateTopicMessagesStreamL(): (11)");
- CleanupStack::PopAndDestroy(); // disk space
- sharedData.Close();
- }
-
- CBSLOGSTRING("CBSSERVER: <<< CCbsDbImpTopicMessages::UpdateTopicMessagesStreamL()");
- }
-
-// -----------------------------------------------------------------------------
-// CCbsDbImpTopicMessages::WriteTopicMessagesStreamL
-// Writes topic messages stream from the internal cache.
-// (other items were commented in a header).
-// -----------------------------------------------------------------------------
-//
-void CCbsDbImpTopicMessages::WriteTopicMessagesStreamL(
- RWriteStream& aOut )
- {
- // Write total amount of messages.
- TInt count( iMessageList->Count() );
- aOut.WriteInt16L( count );
-
- // Write total amount of space for messages.
- aOut.WriteInt16L( iSpaceForMessages );
-
- TInt index( 0 );
-
- for ( ; index < count; index++ )
- {
- CbsStreamHelper::WriteBoolL( aOut,
- iMessageList->At( index ).iIsSaved );
-
- // Write message stream id.
- aOut << iMessageList->At( index ).iId;
- }
-
- for ( ; index < iSpaceForMessages; index++ )
- {
- CbsStreamHelper::WriteBoolL( aOut, EFalse );
-
- // Write null message stream id.
- aOut << TStreamId( 0 );
- }
- }
-
-// -----------------------------------------------------------------------------
-// CCbsDbImpTopicMessages::CreateMessageContentsStreamL
-// Creates a new message content stream and writes
-// the given contents into this stream.
-// (other items were commented in a header).
-// -----------------------------------------------------------------------------
-//
-TStreamId CCbsDbImpTopicMessages::CreateMessageContentsStreamL(
- CStreamStore& aStore,
- const TDesC& aContents )
- {
- // Create stream and write data to it.
- RStoreWriteStream outstream;
- TStreamId id( outstream.CreateLC( aStore ) ); // on CS
-
- // Just write the contents..
- TInt count( aContents.Length() );
- outstream.WriteInt16L( count );
- outstream << aContents;
-
- outstream.CommitL();
- CleanupStack::PopAndDestroy(); // outstream
-
- return id;
- }
-
-// -----------------------------------------------------------------------------
-// CCbsDbImpTopicMessages::CreateMessageStreamL
-// Creates a message stream and
-// writes the message into that stream.
-// (other items were commented in a header).
-// -----------------------------------------------------------------------------
-//
-TStreamId CCbsDbImpTopicMessages::CreateMessageStreamL(
- CStreamStore& aStore,
- TCbsDbMessage& aMessage,
- const TStreamId& aContents )
- {
- // Create stream and write data to it.
- RStoreWriteStream outstream;
- TStreamId id = outstream.CreateLC( aStore ); // on CS
-
- // Write the handle.
- outstream.WriteInt32L( aMessage.iHandle );
-
- // Write the message key.
- outstream.WriteInt16L( aMessage.iKey );
-
- // Write the language.
- outstream.WriteInt16L( aMessage.iLanguage );
-
- // Write the date and time.
- outstream << aMessage.iDateTime;
-
- // Write the permanent status.
- CbsStreamHelper::WriteBoolL( outstream, aMessage.iPermanent );
-
- // Write the read status.
- CbsStreamHelper::WriteBoolL( outstream, aMessage.iRead );
-
- // Write the stream identifier to the contents.
- outstream << aContents;
-
- outstream.CommitL();
- CleanupStack::PopAndDestroy(); // outstream
-
- return id;
- }
-
-// -----------------------------------------------------------------------------
-// CCbsDbImpTopicMessages::ReadTopicMessagesCacheItemsL
-// Reads all cache items for a topic.
-// Restores topic message cache from a stream.
-// (other items were commented in a header).
-// -----------------------------------------------------------------------------
-//
-void CCbsDbImpTopicMessages::ReadTopicMessagesCacheItemsL(
- const CStreamStore& aStore,
- const TStreamId& aId,
- TCbsDbImpTopicMessagesCache& aCache,
- TInt& aSpace )
- {
- CBSLOGSTRING("CBSSERVER: >>> CCbsDbImpTopicMessages::ReadTopicMessagesCacheItemsL()");
-
- RStoreReadStream instream;
- instream.OpenLC( aStore, aId ); // on CS
- CBSLOGSTRING("CBSSERVER: CCbsDbImpTopicMessages::ReadTopicMessagesCacheItemsL(): instream.OpenLC() OK.");
-
- // Read total amount of messages.
- TInt totalMessages( instream.ReadInt16L() );
- CBSLOGSTRING2("CBSSERVER: CCbsDbImpTopicMessages::ReadTopicMessagesCacheItemsL(): totalMessages: %d.", totalMessages );
-
- // Read total amount of space for messages.
- aSpace = instream.ReadInt16L();
- CBSLOGSTRING2("CBSSERVER: CCbsDbImpTopicMessages::ReadTopicMessagesCacheItemsL(): aSpace: %d.", aSpace );
-
- // Sanity check: if the number of messages exceeds
- // the worst case, leave. If the space for messages
- // is smaller than number of messages, leave.
- if ( totalMessages > KCbsDbMaxSavedMessages + KCbsDbMaxReceivedMessages
- || aSpace < totalMessages )
- {
- CBSLOGSTRING("CBSSERVER: CCbsDbImpTopicMessages::ReadTopicMessagesCacheItemsL(): Stream corrupt, leaving with KErrCorrupt...");
- User::Leave( KErrCorrupt );
- }
-
- TCbsDbImpTopicMessagesCacheItem item;
-
- aCache.Reset();
-
- for ( TInt index( 0 ); index < totalMessages; index++ )
- {
- CBSLOGSTRING2("CBSSERVER: CCbsDbImpTopicMessages::ReadTopicMessagesCacheItemsL(): Looping msgs, i: %d.", index );
- item.iIsSaved = CbsStreamHelper::ReadBoolL( instream );
-
- // Read topic message stream id.
- instream >> item.iId;
-
- // Initialize other fields.
- item.iIsMessage = EFalse;
-
- // And finally, append the item to the array
- aCache.AppendL( item );
-
- CBSLOGSTRING("CBSSERVER: CCbsDbImpTopicMessages::ReadTopicMessagesCacheItemsL(): Msg appended to array.");
- }
-
- CleanupStack::PopAndDestroy(); // instream
-
- CBSLOGSTRING("CBSSERVER: <<< CCbsDbImpTopicMessages::ReadTopicMessagesCacheItemsL()");
- }
-
-// -----------------------------------------------------------------------------
-// CCbsDbImpTopicMessages::ReadMessageInformationL
-// Restore a message from a stream.
-// (other items were commented in a header).
-// -----------------------------------------------------------------------------
-//
-void CCbsDbImpTopicMessages::ReadMessageInformationL(
- const CStreamStore& aStore,
- const TStreamId& aId,
- TCbsDbMessage& aMessage,
- TStreamId& aContentsId )
- {
- CBSLOGSTRING("CBSSERVER: >>> CCbsDbImpTopicMessages::ReadMessageInformationL()");
-
- // Open the message information stream.
- RStoreReadStream instream;
- instream.OpenLC( aStore, aId ); // on CS
-
- // Read the handle.
- aMessage.iHandle = instream.ReadInt32L();
-
- // Read the message key.
- aMessage.iKey = instream.ReadInt16L();
-
- // Read the language.
- aMessage.iLanguage = instream.ReadInt16L();
-
- // Read the date and time.
- TInt64 time;
- instream >> time;
- aMessage.iDateTime = time;
-
- // Read the permanent status.
- aMessage.iPermanent = CbsStreamHelper::ReadBoolL( instream );
-
- // Read the read status.
- aMessage.iRead = CbsStreamHelper::ReadBoolL( instream );
-
- // Read the stream identifier to the contents.
- instream >> aContentsId;
-
- CleanupStack::PopAndDestroy(); // instream
-
- if ( aContentsId == TStreamId( 0 ) )
- {
- aMessage.iLength = 0;
- }
- else
- {
- // Open message contents stream.
- RStoreReadStream instreamContents;
-
- instreamContents.OpenLC( aStore, aContentsId ); // on CS
-
- // Read the length of the message.
- aMessage.iLength = instreamContents.ReadInt16L();
-
- CleanupStack::PopAndDestroy(); // instreamContents
- }
- CBSLOGSTRING("CBSSERVER: <<< CCbsDbImpTopicMessages::ReadMessageInformationL()");
- }
-
-// -----------------------------------------------------------------------------
-// CCbsDbImpTopicMessages::WriteMessageInformationL
-// Writes message information into a stream.
-// (other items were commented in a header).
-// -----------------------------------------------------------------------------
-//
-void CCbsDbImpTopicMessages::WriteMessageInformationL(
- RWriteStream& aOut,
- const TCbsDbMessage& aMessage,
- const TStreamId& aContentsId )
- {
- // Write the handle.
- aOut.WriteInt32L( aMessage.iHandle );
-
- // Write the message key.
- aOut.WriteInt16L( aMessage.iKey );
-
- // Write the language.
- aOut.WriteInt16L( aMessage.iLanguage );
-
- // Write the date and time.
- aOut << aMessage.iDateTime;
-
- // Write the permanent status.
- CbsStreamHelper::WriteBoolL( aOut, aMessage.iPermanent );
-
- // Write the read status.
- CbsStreamHelper::WriteBoolL( aOut, aMessage.iRead );
-
- // Write the stream identifier to the contents.
- aOut << aContentsId;
- }
-
-// -----------------------------------------------------------------------------
-// CCbsDbImpTopicMessages::UpdateSoftNotificationL
-// Updates the soft notification (dialog) when unread message count changes.
-// (other items were commented in a header).
-// -----------------------------------------------------------------------------
-//
-void CCbsDbImpTopicMessages::UpdateSoftNotificationL(
- const TCbsDbMessageHandle& aHandle,
- const CCbsRecEtel& aReceiver )
- {
- TCbsDbTopic topic;
- TCbsDbTopicNumber topicNum( iTopicList.ExtractTopicNumber( aHandle ) );
- iTopicList.FindTopicByNumberL( topicNum, topic );
-
- // If topic is hotmarked, update the soft notification (dialog) ,
- // since number of read messages was changed
- if ( topic.iHotmarked )
- {
- aReceiver.Interface().LaunchMessageSoftNotificationL( EFalse );
- }
- }
-
-// -----------------------------------------------------------------------------
-// CCbsDbImpTopicMessages::RevertFileOperationL
-// Reverts any not commited file operation in data files,
-// reloads cache and then leaves with aReason.
-// (other items were commented in a header).
-// -----------------------------------------------------------------------------
-//
-void CCbsDbImpTopicMessages::RevertFileOperationL(
- TInt aReason )
- {
- iTopicList.RevertFilesL();
- InvalidateCache();
- User::Leave( aReason );
- }
-
-// ========================== OTHER EXPORTED FUNCTIONS =========================
-
-// End of File