--- a/remotestoragefw/remotefileengine/src/rsfwpermanentstore.cpp Wed Jun 09 10:37:35 2010 +0300
+++ /dev/null Thu Jan 01 00:00:00 1970 +0000
@@ -1,885 +0,0 @@
-/*
-* Copyright (c) 2004-2006 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: Provides persistent storage for memory blocks
-*
-*/
-
-
-// This is a simple block based permanent storage, in which transient
-// indices are computed on the fly when all data is sequentially read
-// from the storage.
-//
-// The data is put into "slots" that consist of one or more "blocks".
-// Subsequent updates to the data slots only use the current slot
-// if the required slot size (block count) has not changed.
-//
-// The storage contains a header that may contain any data.
-// In addition, Each slot contains a header (of type TInt) that
-// describes the size of the data in the slot.
-//
-// The file can be compressed for space efficiency.
-//
-// The assumption is that the store is first opened for reading for loading
-// the data, and then it is only opened for writing until the file is closed.
-//
-// (We don't use CRsfwPermanentStore because besides data, we should
-// also maintain the indices in a stream of its own)
-
-// INCLUDE FILES
-#include <s32strm.h>
-#include <s32buf.h>
-
-#include "rsfwpermanentstore.h"
-#include "mdebug.h"
-
-
-// CONSTANTS
-const TUint KHeaderStart = 0xbabefade;
-const TInt KSlotHeaderSize = 4; // sizeof(TInt)
-const TInt KDefaultBlockSize = 128; // default block size in bytes
-// max value for integer read from the stream, subsequently used to create descriptor
-const TInt KMaxDescriptorSize = 16384;
-
-
-// ============================ MEMBER FUNCTIONS ==============================
-
-// ----------------------------------------------------------------------------
-// TFileHeader::ExternalizeL
-// ----------------------------------------------------------------------------
-//
-void TFileHeader::ExternalizeL(RWriteStream& aStream) const
- {
- aStream.WriteInt32L(iHeaderStart);
- aStream.WriteInt32L(iBlockSize);
- aStream.WriteInt32L(iHeaderSize);
- aStream << *iHeader;
- }
-
-// ----------------------------------------------------------------------------
-// TFileHeader::InternalizeL
-// ----------------------------------------------------------------------------
-//
-void TFileHeader::InternalizeL(RReadStream& aStream)
- {
- iHeaderStart = aStream.ReadInt32L();
- iBlockSize = aStream.ReadInt32L();
- if (iBlockSize < 0 || iBlockSize > KMaxDescriptorSize)
- {
- User::Leave(KErrCorrupt);
- }
- iHeaderSize = aStream.ReadInt32L();
- if (iHeaderSize < 0 || iHeaderSize > KMaxDescriptorSize)
- {
- User::Leave(KErrCorrupt);
- }
- iHeader = HBufC8::NewL(aStream, iHeaderSize);
- }
-
-// ----------------------------------------------------------------------------
-// CRsfwPermanentStore::NewL
-// ----------------------------------------------------------------------------
-//
-CRsfwPermanentStore* CRsfwPermanentStore::NewL(const TDesC& aPath,
- TInt aHeaderSize,
- TInt aBlockSize)
- {
- CRsfwPermanentStore* self = new (ELeave) CRsfwPermanentStore();
- CleanupStack::PushL(self);
- self->ConstructL(aPath, aHeaderSize, aBlockSize);
- CleanupStack::Pop(self);
- return self;
- }
-
-// ----------------------------------------------------------------------------
-// CRsfwPermanentStore::~CRsfwPermanentStore
-// ----------------------------------------------------------------------------
-//
-CRsfwPermanentStore::~CRsfwPermanentStore()
- {
- ClearFreeBlockLists();
- iSlots.Close();
- iFileReadStream.Close();
- iFileWriteStream.Close();
- iFile.Close();
- iFs.Close();
- delete iFileHeader.iHeader;
- delete iZeroBlock;
- }
-
-// ----------------------------------------------------------------------------
-// CRsfwPermanentStore::ConstructL
-// ----------------------------------------------------------------------------
-//
-void CRsfwPermanentStore::ConstructL(const TDesC& aPath,
- TInt aHeaderSize,
- TInt aBlockSize)
- {
- DEBUGSTRING(("CRsfwPermanentStore::ConstructL()"));
- User::LeaveIfError(iFs.Connect());
- iPath.Copy(aPath);
-
- iHeaderSize = aHeaderSize;
- // Offset to the block data
- iFileHeaderSize = iHeaderSize + sizeof(TFileHeader);
- TRAPD(err, LoadHeaderL());
- if (err == KErrNone)
- {
- // Read parameters from the existing file, if any
- iHeaderSize = iFileHeader.iHeaderSize;
- iBlockSize = iFileHeader.iBlockSize;
- }
- else
- {
- // There was no existing file
- DEBUGSTRING(("LoadHeaderL returns %d", err));
- if (aBlockSize)
- {
- iBlockSize = aBlockSize;
- }
- else
- {
- iBlockSize = KDefaultBlockSize;
- }
- iFileHeader.iHeaderStart = KHeaderStart;
- iFileHeader.iHeaderSize = iHeaderSize;
- iFileHeader.iBlockSize = iBlockSize;
- }
- // Compute the offset to data blocks
- // (this is 4 bytes too many but that is OK ...)
- iFileHeaderSize = iHeaderSize + sizeof(TFileHeader);
- // Make a block of zeroes
- iZeroBlock = HBufC8::NewL(iBlockSize);
- iZeroBlock->Des().FillZ();
- DEBUGSTRING(("ConstructL() done, blocksize=%d", iBlockSize));
- }
-
-// ----------------------------------------------------------------------------
-// CRsfwPermanentStore::ResetL
-// ----------------------------------------------------------------------------
-//
-void CRsfwPermanentStore::ResetL(TBool aWriting)
- {
- // This function is called by the client
- // before starting to read or write data slots
- if (aWriting)
- {
- SetFileStateL(EFileStateWriting);
- // Set write pointer to the end of the file
- MStreamBuf* streamBuf = iFileWriteStream.Sink();
- TInt size = streamBuf->SizeL();
- iWriteBlockNumber = (size - iFileHeaderSize) / iBlockSize;
- if ((iWriteBlockNumber * iBlockSize) != (size - iFileHeaderSize))
- {
- DEBUGSTRING(("ResetL(): file size incorrect (%d)",
- size));
- }
- }
- else
- {
- // reading
- SetFileStateL(EFileStateReading);
- // Skip file header
- MStreamBuf* streamBuf = iFileReadStream.Source();
- streamBuf->SeekL(MStreamBuf::ERead,
- EStreamBeginning,
- iFileHeaderSize);
- iReadBlockNumber = 0;
- }
- }
-
-// ----------------------------------------------------------------------------
-// CRsfwPermanentStore::Commit
-// ----------------------------------------------------------------------------
-//
-TInt CRsfwPermanentStore::Commit()
- {
- TInt err = KErrNone;
- // Commit writing
- if (iFileState == EFileStateWriting)
- {
- MStreamBuf* streamBuf = iFileWriteStream.Sink();
- err = streamBuf->Synch();
- }
- return err;
- }
-
-// ----------------------------------------------------------------------------
-// CRsfwPermanentStore::Purge
-// ----------------------------------------------------------------------------
-//
-TInt CRsfwPermanentStore::Purge()
- {
- iFileReadStream.Close();
- iFileWriteStream.Close();
- iFile.Close();
- return iFs.Delete(iPath);
- }
-
-// ----------------------------------------------------------------------------
-// CRsfwPermanentStore::CompactL
-// ----------------------------------------------------------------------------
-//
-void CRsfwPermanentStore::CompactL()
- {
- // Compact the file by dropping empty slots.
- // The slot table is also fixed and the free block lists are cleared
- // to reflect the new file layout.
-
- // This function must not be called while the file is opened for reading.
- // It is most efficient to call this function before any data is read
- // (then there is no slot table to fix)
-
- // This function must be called before doing GetNextDataL()
- // (must be followed by ResetL()).
- // However, this function can be called while doing PutDataL().
-
- DEBUGSTRING(("CompactL()"));
- SetFileStateL(EFileStateClosed);
- SetFileStateL(EFileStateReading);
-
- TBuf<KMaxPath> dstPath;
- dstPath.Copy(iPath);
- dstPath.Append('a');
- RFile dstFile;
- User::LeaveIfError(dstFile.Replace(iFs,
- dstPath,
- EFileShareAny | EFileWrite));
- CleanupClosePushL(dstFile);
- RFileWriteStream dstFileWriteStream(dstFile);
- CleanupClosePushL(dstFileWriteStream);
- MStreamBuf* streamBuf = iFileReadStream.Source();
-
- // Copy header
- dstFileWriteStream.WriteL(iFileReadStream, iFileHeaderSize);
-
- RArray<TSlot> gaps;
- CleanupClosePushL(gaps);
-
- TInt blockNumber = 0;
- TInt lastReadBlockNumber = 0;
- TInt nextWriteBlockNumber = 0;
- TInt err = KErrNone;
- while (err == KErrNone)
- {
- TSlot gap;
- TInt dataLength = 0;
- TRAP(err, dataLength = iFileReadStream.ReadInt32L());
- if (err == KErrNone)
- {
- TInt blockCount;
- if (dataLength >= 0)
- {
- // real data
- blockCount = BlockCount(dataLength);
-#if 0
- DEBUGSTRING(("Copying at block %d, count %d",
- blockNumber,
- blockCount));
-#endif
- // Back off four bytes
- streamBuf->SeekL(MStreamBuf::ERead,
- EStreamMark,
- -KSlotHeaderSize);
- dstFileWriteStream.WriteL(iFileReadStream,
- blockCount * iBlockSize);
- lastReadBlockNumber = blockNumber;
- nextWriteBlockNumber += blockCount;
- }
- else
- {
- // empty slot
- DEBUGSTRING(("Compacting at block %d", blockNumber));
- blockCount = -dataLength;
- streamBuf->SeekL(MStreamBuf::ERead,
- EStreamMark,
- blockCount * iBlockSize - KSlotHeaderSize);
- // Mark block position
- gap.iIndex = 0; // not needed here
- gap.iBlockNumber = blockNumber;
- gap.iBlockCount = blockCount;
- gaps.Append(gap);
- }
- blockNumber += blockCount;
- }
- }
- if (err == KErrEof)
- {
- err = KErrNone;
- }
- // Replace old file with the compressed file
- SetFileStateL(EFileStateClosed);
- dstFileWriteStream.Close();
- dstFile.Close();
- if ((err == KErrNone) && gaps.Count())
- {
- // No errors and some compaction was achieved
- err = iFs.Delete(iPath);
- if (err == KErrNone)
- {
- err = iFs.Rename(dstPath, iPath);
- if (err == KErrNone)
- {
- DEBUGSTRING(("CompactL(): gaps %d slots %d",
- gaps.Count(),
- iSlots.Count()));
- if (gaps.Count() && iSlots.Count())
- {
- // Fix slot table (0(n**2))
- TInt oldBlockNumber = 0;
- TInt newBlockNumber = 0;
- while (oldBlockNumber <= lastReadBlockNumber)
- {
- if (gaps.Count())
- {
- // still more gaps ...
- if (oldBlockNumber == gaps[0].iBlockNumber)
- {
- oldBlockNumber += gaps[0].iBlockCount;
- gaps.Remove(0);
- }
- }
- if (oldBlockNumber != newBlockNumber)
- {
- FixSlot(oldBlockNumber, newBlockNumber);
- }
- oldBlockNumber++;
- newBlockNumber++;
- }
- }
- }
- }
- // Clear free block lists
- ClearFreeBlockLists();
- // Setup next block to write
- iWriteBlockNumber = nextWriteBlockNumber;
- }
- else
- {
- // Some error occured or no compaction was achieved
- TInt r = iFs.Delete(dstPath);
-#ifdef _DEBUG
- DEBUGSTRING(("CompactL(): destination file deletion returns %d ", r));
-#endif
- }
-
- CleanupStack::PopAndDestroy(3, &dstFile); // gaps, dstFileWriteStream, dstFile
- }
-
-// ----------------------------------------------------------------------------
-// CRsfwPermanentStore::SetHeaderL
-// ----------------------------------------------------------------------------
-//
-void CRsfwPermanentStore::SetHeaderL(TDesC8& aHeader)
- {
- delete iFileHeader.iHeader;
- iFileHeader.iHeader = NULL;
- iFileHeader.iHeader = aHeader.AllocL();
- }
-
-// ----------------------------------------------------------------------------
-// CRsfwPermanentStore::Header
-// ----------------------------------------------------------------------------
-//
-const HBufC8* CRsfwPermanentStore::Header()
- {
- if (iFileHeader.iHeader)
- {
- return iFileHeader.iHeader;
- }
- else
- {
- return NULL;
- }
- }
-
-// ----------------------------------------------------------------------------
-// CRsfwPermanentStore::GetNextDataL
-// ----------------------------------------------------------------------------
-//
-void CRsfwPermanentStore::GetNextDataL(TUint8* aData,
- TInt& aDataLength,
- TInt& aIndex)
- {
- // Return the next slotful of data.
- // This function must only be used for sequential access
- SetFileStateL(EFileStateReading);
-
- MStreamBuf* streamBuf = iFileReadStream.Source();
-
- TBool done = EFalse;
- while (!done)
- {
- TInt dataLength = 0;
- // Eventually leaves with KErrEof
- dataLength = iFileReadStream.ReadInt32L();
- TInt blockCount;
- if (dataLength >= 0)
- {
- // Fill data
- iFileReadStream.ReadL(aData, dataLength);
- aDataLength = dataLength;
- aIndex = iIndex;
-
- // Update block map
- blockCount = BlockCount(dataLength);
-#if 0
- DEBUGSTRING((
- "GetNextDataL(): index=%d, block=%d, count=%d, len=%d",
- iIndex,
- iReadBlockNumber,
- blockCount,
- dataLength));
-#endif
-
- ReserveSlot(iIndex, iReadBlockNumber, blockCount);
- iIndex++;
- iReadBlockNumber += blockCount;
-
- // Update read position to the start of next block
- TInt offset = iBlockSize -
- (KSlotHeaderSize + dataLength) % iBlockSize;
- if (offset != iBlockSize)
- {
- streamBuf->SeekL(MStreamBuf::ERead, EStreamMark, offset);
- }
-
- done = ETrue;
- }
- else
- {
- // Negative length indicates a number of free blocks.
- // Put such empty blocks into the free block list
- blockCount = -dataLength;
- PutToFreeBlockList(iReadBlockNumber, blockCount);
-
- // Seek to the next slot
- streamBuf->SeekL(MStreamBuf::ERead,
- EStreamMark,
- blockCount * iBlockSize - KSlotHeaderSize);
- iReadBlockNumber += blockCount;
- }
- }
- }
-
-// ----------------------------------------------------------------------------
-// CRsfwPermanentStore::PutDataL
-// ----------------------------------------------------------------------------
-//
-void CRsfwPermanentStore::PutDataL(const TUint8* aData,
- TInt aDataLength,
- TInt& aIndex)
- {
- // Write data with the given index
- // If the index < 0, this a new data
- SetFileStateL(EFileStateWriting);
-
- if (aDataLength == 0)
- {
- // We just want to dispose of the slot
- ClearSlotL(aIndex);
- return;
- }
-
- TBool done = EFalse;
- TInt blockCount = BlockCount(aDataLength);
- if (aIndex >= 0)
- {
- // Check if we have space in the existing slot
- TSlot* slot = Slot(aIndex);
- // We should always find the slot
- if (slot)
- {
- if (slot->iBlockCount == blockCount)
- {
- // We can use the current slot
- WriteBlocksL(aData, aDataLength, slot->iBlockNumber);
- done = ETrue;
- }
- else
- {
- // Clear the slot
- ClearSlotL(aIndex);
- }
- }
- else
- {
- DEBUGSTRING(("Slot %d not found!", aIndex));
- }
- }
- else
- {
- // Allocate new index
- aIndex = iIndex++;
- }
-
- if (!done)
- {
- // Try to get a free slot
- TInt blockNumber = GetFromFreeBlockList(blockCount);
- if (blockNumber == KErrNotFound)
- {
- // We have to append to the file
- blockNumber = iWriteBlockNumber;
- iWriteBlockNumber += blockCount;
- }
-
- ReserveSlot(aIndex, blockNumber, blockCount);
- WriteBlocksL(aData, aDataLength, blockNumber);
- }
- }
-
-// ----------------------------------------------------------------------------
-// CRsfwPermanentStore::BlockCount
-// ----------------------------------------------------------------------------
-//
-TInt CRsfwPermanentStore::BlockCount(TInt aDataLength)
- {
- // Get the block count for a given data size
- return (KSlotHeaderSize + aDataLength - 1) / iBlockSize + 1;
- }
-
-// ----------------------------------------------------------------------------
-// CRsfwPermanentStore::StreamPosition
-// ----------------------------------------------------------------------------
-//
-TInt CRsfwPermanentStore::StreamPosition(TInt aBlockNumber)
- {
- // Get the stream position from block position
- return (iFileHeaderSize + aBlockNumber * iBlockSize);
- }
-
-// ----------------------------------------------------------------------------
-// CRsfwPermanentStore::Slot
-// ----------------------------------------------------------------------------
-//
-TSlot* CRsfwPermanentStore::Slot(TInt aIndex)
- {
- // Find the slot with the given index
- TSlot slot; // dummy slot for Find()
- slot.iIndex = aIndex;
- TInt i = iSlots.Find(slot);
- if (i != KErrNotFound)
- {
- return &iSlots[i];
- }
- else
- {
- return NULL;
- }
- }
-
-// ----------------------------------------------------------------------------
-// CRsfwPermanentStore::FixSlot
-// ----------------------------------------------------------------------------
-//
-void CRsfwPermanentStore::FixSlot(TInt aOldBlockNumber, TInt aNewBlockNumber)
- {
- // Assign a new starting block to the slot that used to
- // start at aOldBlockNumber.
- // The block numbers are changed due to compaction -
- // thus the block numbers can only become smaller.
- TInt i;
- for (i = 0; i < iSlots.Count(); i++)
- {
- TSlot& slot = iSlots[i];
- // Note that this function can also be called with block numbers
- // that do not start a slot - then there will be no match
- if (slot.iBlockNumber == aOldBlockNumber)
- {
- DEBUGSTRING(("Fixing slot %d = %d",
- aOldBlockNumber,
- aNewBlockNumber));
- slot.iBlockNumber = aNewBlockNumber;
- return;
- }
- }
- }
-
-// ----------------------------------------------------------------------------
-// CRsfwPermanentStore::SetFileStateL
-// ----------------------------------------------------------------------------
-//
-void CRsfwPermanentStore::SetFileStateL(TInt aFileState)
- {
- DEBUGSTRING(("CRsfwPermanentStore::SetFileStateL"));
- DEBUGSTRING(("iFileState = %d, aFileState = %d", iFileState, aFileState));
- if (iFileState != aFileState)
- {
- switch (iFileState)
- {
- case EFileStateClosed:
- {
- if (aFileState == EFileStateReading)
- {
- DEBUGSTRING(("opening a closed file for reading"));
- DEBUGSTRING16(("path is %S", &iPath));
- User::LeaveIfError(iFile.Open(iFs,
- iPath,
- EFileShareAny | EFileRead));
- TInt size;
- iFile.Size(size);
- DEBUGSTRING(("opening successfull, file size is %d", size));
- DEBUGSTRING(("header size %d", iFileHeaderSize));
- // sanity
- if (size < iFileHeaderSize)
- {
- // Close the file and leave the file state as "closed"
- iFile.Close();
- User::Leave(KErrNotFound);
- }
- else
- {
- iFileReadStream.Attach(iFile);
- }
- }
- else
- {
- // EFileStateWriting
- TInt err = iFile.Open(iFs, iPath, EFileShareAny | EFileWrite);
- if (err != KErrNone)
- {
- // The file did not exist
- User::LeaveIfError(
- iFile.Create(iFs,
- iPath,
- EFileShareAny | EFileWrite));
- }
- TInt size;
- User::LeaveIfError(iFile.Size(size));
- iFileWriteStream.Attach(iFile);
- if (size < iFileHeaderSize)
- {
- // Store header if this was a new file
- SaveHeaderL();
- }
- }
- }
- break;
-
- case EFileStateReading:
- case EFileStateWriting:
- {
- // close and redo
- if (iFileState == EFileStateReading)
- {
- iFileReadStream.Close();
- }
- else
- {
- iFileWriteStream.Close();
- }
- iFile.Close();
- iFileState = EFileStateClosed;
- SetFileStateL(aFileState);
- }
- break;
-
- default:
- break;
- }
-
- iFileState = aFileState;
- }
- }
-
-// ----------------------------------------------------------------------------
-// CRsfwPermanentStore::LoadHeaderL
-// ----------------------------------------------------------------------------
-//
-void CRsfwPermanentStore::LoadHeaderL()
- {
- DEBUGSTRING(("CRsfwPermanentStore::LoadHeaderL"));
- SetFileStateL(EFileStateReading);
- iFileHeader.InternalizeL(iFileReadStream);
- ResetL(EFalse);
- }
-
-// ----------------------------------------------------------------------------
-// CRsfwPermanentStore::SaveHeaderL
-// ----------------------------------------------------------------------------
-//
-void CRsfwPermanentStore::SaveHeaderL()
- {
- // Write header with filler
- iFileHeader.ExternalizeL(iFileWriteStream);
- MStreamBuf* streamBuf = iFileWriteStream.Sink();
- TInt fileHeaderSize = streamBuf->TellL(MStreamBuf::EWrite).Offset();
- TInt residue = iFileHeaderSize - fileHeaderSize;
- HBufC8* fill = HBufC8::NewLC(residue);
- TPtr8 fillZ = fill->Des();
- fillZ.SetLength(residue);
- fillZ.FillZ();
- DEBUGSTRING(("SaveHeader(): header=%d, filler=%d",
- iFileHeaderSize,
- fillZ.Length()));
- iFileWriteStream.WriteL(fillZ);
- Commit();
- CleanupStack::PopAndDestroy(fill); // fill
- }
-
-// ----------------------------------------------------------------------------
-// CRsfwPermanentStore::ClearFreeBlockLists
-// ----------------------------------------------------------------------------
-//
-void CRsfwPermanentStore::ClearFreeBlockLists()
- {
- TInt i;
- for (i = 0; i < iFreeBlockLists.Count(); i++)
- {
- iFreeBlockLists[i].iFreeBlockList.Close();
- }
- iFreeBlockLists.Close();
- }
-
-// ----------------------------------------------------------------------------
-// CRsfwPermanentStore::ClearSlotL
-// ----------------------------------------------------------------------------
-//
-void CRsfwPermanentStore::ClearSlotL(TInt aIndex)
- {
- // Mark a slot as unused in the file and
- // add the slot in the free block list
-
- TSlot s; // dummy slot for iSlots.Find()
- s.iIndex = aIndex;
- TInt i = iSlots.Find(s);
- if (i != KErrNotFound)
- {
- TSlot& slot = iSlots[i];
- // Mark the slot in the file as empty
- TInt pos = iFileHeaderSize + slot.iBlockNumber * iBlockSize;
-
- DEBUGSTRING(("ClearSlotL(): index=%d, block=%d, count=%d, pos=%d",
- aIndex,
- slot.iBlockNumber,
- slot.iBlockCount,
- pos));
-
- MStreamBuf* streamBuf = iFileWriteStream.Sink();
- streamBuf->SeekL(MStreamBuf::EWrite, EStreamBeginning, pos);
- iFileWriteStream.WriteInt32L(-slot.iBlockCount);
-
- // Add the slot in the free block list
- PutToFreeBlockList(slot.iBlockNumber, slot.iBlockCount);
-
- // Delete the slot from the slot table
- iSlots.Remove(i);
- }
- else
- {
- DEBUGSTRING(("ClearSlotL(): index=%d not found!", aIndex));
- User::Leave(KErrNotFound);
- }
- }
-
-// ----------------------------------------------------------------------------
-// CRsfwPermanentStore::WriteBlocksL
-// ----------------------------------------------------------------------------
-//
-void CRsfwPermanentStore::WriteBlocksL(const TUint8* aData,
- TInt aDataLength,
- TInt aBlockNumber)
- {
- // Put the given data in the slot specified by the index
- TInt pos = iFileHeaderSize + aBlockNumber * iBlockSize;
-
-#if 0
- DEBUGSTRING(("WriteBlocksL(): block=%d, len=%d, pos=%d",
- aBlockNumber,
- aDataLength,
- pos));
-#endif
-#if 0
- TInt size;
- iFile.Size(size);
-
- DEBUGSTRING(("size=%d", size));
-#endif
-
- MStreamBuf* streamBuf = iFileWriteStream.Sink();
- streamBuf->SeekL(MStreamBuf::EWrite, EStreamBeginning, pos);
-
- // Write the data in the file (preceded by the length)
- iFileWriteStream.WriteInt32L(aDataLength);
- iFileWriteStream.WriteL(aData, aDataLength);
-
- // We have to fill the whole slot if this is the last slot
- // in the file. Well, we will will the last bock of all slots
- TInt residue = iBlockSize - (KSlotHeaderSize + aDataLength) % iBlockSize;
- if (residue != iBlockSize)
- {
- iFileWriteStream.WriteL(iZeroBlock->Des().Ptr(), residue);
- }
- }
-
-// ----------------------------------------------------------------------------
-// CRsfwPermanentStore::ReserveSlot
-// ----------------------------------------------------------------------------
-//
-void CRsfwPermanentStore::ReserveSlot(TInt aIndex,
- TInt aBlockNumber,
- TInt aBlockCount)
- {
- TSlot slot;
-
- slot.iIndex = aIndex;
- slot.iBlockNumber = aBlockNumber;
- slot.iBlockCount = aBlockCount;
- iSlots.Append(slot);
- }
-
-
-// ----------------------------------------------------------------------------
-// CRsfwPermanentStore::PutToFreeBlockList
-// ----------------------------------------------------------------------------
-//
-void CRsfwPermanentStore::PutToFreeBlockList(TInt aBlockPos, TInt aBlockCount)
- {
- while (iFreeBlockLists.Count() < aBlockCount)
- {
- // Construct list until blockCount size
- TFreeBlockList freeBlockList;
- iFreeBlockLists.Append(freeBlockList);
- }
- iFreeBlockLists[aBlockCount - 1].iFreeBlockList.Append(aBlockPos);
- }
-
-// ----------------------------------------------------------------------------
-// CRsfwPermanentStore::GetFromFreeBlockList
-// ----------------------------------------------------------------------------
-//
-TInt CRsfwPermanentStore::GetFromFreeBlockList(TInt aBlockCount)
- {
- // Only support exact matches.
- // That is, bigger slots are not broken into smaller slots
- if (iFreeBlockLists.Count() < aBlockCount)
- {
- // no list
- return KErrNotFound;
- }
-
- TFreeBlockList& freeBlockList = iFreeBlockLists[aBlockCount - 1];
- if (freeBlockList.iFreeBlockList.Count() == 0)
- {
- // no entries in the list
- return KErrNotFound;
- }
-
- // Get the first entry in the list
- TInt blockPos = freeBlockList.iFreeBlockList[0];
- freeBlockList.iFreeBlockList.Remove(0);
- return blockPos;
- }
-
-// End of File