os/graphics/fbs/fontandbitmapserver/sfbs/FBSMBMC.CPP
author sl@SLION-WIN7.fritz.box
Fri, 15 Jun 2012 03:10:57 +0200
changeset 0 bde4ae8d615e
permissions -rw-r--r--
First public contribution.
sl@0
     1
// Copyright (c) 2004-2009 Nokia Corporation and/or its subsidiary(-ies).
sl@0
     2
// All rights reserved.
sl@0
     3
// This component and the accompanying materials are made available
sl@0
     4
// under the terms of "Eclipse Public License v1.0"
sl@0
     5
// which accompanies this distribution, and is available
sl@0
     6
// at the URL "http://www.eclipse.org/legal/epl-v10.html".
sl@0
     7
//
sl@0
     8
// Initial Contributors:
sl@0
     9
// Nokia Corporation - initial contribution.
sl@0
    10
//
sl@0
    11
// Contributors:
sl@0
    12
//
sl@0
    13
// Description:
sl@0
    14
// This file holds the class methods for the CFbTopMBMCache
sl@0
    15
// 
sl@0
    16
//
sl@0
    17
sl@0
    18
#include "FBSMBMC.H"
sl@0
    19
sl@0
    20
sl@0
    21
//
sl@0
    22
//Constructor for CFbTopMBMCache objects with both forward and backward cache size
sl@0
    23
//The forward(backward) cache size determines the number of stream ids after(before)
sl@0
    24
//the current loaded bitmap ids to be stored in the cache
sl@0
    25
//e.g Loading a bitmap with id=20 from a 40 bitmaps mbm file will load the cache(10,10)
sl@0
    26
//with stream ids from 30-39(10 backward) and 40-49(10 forward)
sl@0
    27
CFbTopStreamIdCache::CFbTopStreamIdCache(TInt aForwardSize, TInt aBackwardSize, TInt aMaxFilestores)
sl@0
    28
	:CBase(),
sl@0
    29
	iEntries(aMaxFilestores),
sl@0
    30
	iForwardCacheSize(aForwardSize),
sl@0
    31
	iBackwardCacheSize(aBackwardSize),
sl@0
    32
	iMaxCacheFilestores(aMaxFilestores)
sl@0
    33
	{
sl@0
    34
	}
sl@0
    35
sl@0
    36
//
sl@0
    37
//Destructor of CFbTopMBMCache objects
sl@0
    38
CFbTopStreamIdCache::~CFbTopStreamIdCache()
sl@0
    39
	{
sl@0
    40
	FlushCache();
sl@0
    41
	}
sl@0
    42
sl@0
    43
//Function to reset all the internal state of the class
sl@0
    44
void CFbTopStreamIdCache::FlushCache()
sl@0
    45
	{
sl@0
    46
	CloseFileStores();
sl@0
    47
	iEntries.Reset();
sl@0
    48
	User::Free(iBuffer);
sl@0
    49
	iBuffer = NULL;
sl@0
    50
	}
sl@0
    51
sl@0
    52
sl@0
    53
//Function to get the most recently used filestore stored in the cache
sl@0
    54
CShiftedFileStore* CFbTopStreamIdCache::MruFileStore()
sl@0
    55
	{
sl@0
    56
	return iEntries[0]->FileStore();
sl@0
    57
	}
sl@0
    58
sl@0
    59
//Function to get the stream id for a bitmap id from a mbm file with certain offset.
sl@0
    60
//It also fills up the cache with the stream ids for different bitmap from the same
sl@0
    61
//mbm file and the number of stream ids stored depend on the initial setting of the
sl@0
    62
//cache size. Also associates each resource with a client handle to improve the
sl@0
    63
//performance of cleaning up.
sl@0
    64
TStreamId CFbTopStreamIdCache::GetStreamIdL(RFile& aFile,const TDesC& aFilename,TInt32 aId,TUint aFileOffset, TInt aSessionHandle)
sl@0
    65
	{
sl@0
    66
	if (aId < 0)
sl@0
    67
		{
sl@0
    68
		User::Leave(KErrEof);
sl@0
    69
		}
sl@0
    70
	RCacheEntry *entry = FindCacheEntry(aFilename, aFileOffset);
sl@0
    71
	if (entry == NULL)
sl@0
    72
		{
sl@0
    73
		entry = AddCacheEntryL(aFilename, aFileOffset);
sl@0
    74
		}
sl@0
    75
	entry->CreateFileStoreL(aFile, aSessionHandle);
sl@0
    76
	return entry->GetStreamIdL(aId, iForwardCacheSize, iBackwardCacheSize);
sl@0
    77
	}
sl@0
    78
sl@0
    79
/**
sl@0
    80
The overloaded version of GetStreamIdL which works with file session instead of file handle.
sl@0
    81
*/
sl@0
    82
TStreamId CFbTopStreamIdCache::GetStreamIdL(RFs& aFs, const TDesC& aFileName,TInt32 aId,TUint aFileOffset, TInt aSessionHandle)
sl@0
    83
	{
sl@0
    84
	if (aId < 0)
sl@0
    85
		{
sl@0
    86
		User::Leave(KErrEof);
sl@0
    87
		}
sl@0
    88
	RCacheEntry *entry = FindCacheEntry(aFileName, aFileOffset);
sl@0
    89
	if (entry == NULL)
sl@0
    90
		{
sl@0
    91
		entry = AddCacheEntryL(aFileName, aFileOffset);
sl@0
    92
		}
sl@0
    93
	entry->CreateFileStoreL(aFs, aFileName, aSessionHandle);
sl@0
    94
	return entry->GetStreamIdL(aId, iForwardCacheSize, iBackwardCacheSize);
sl@0
    95
	}
sl@0
    96
sl@0
    97
void CFbTopStreamIdCache::CloseFileStores(TInt aSessionHandle)
sl@0
    98
	{
sl@0
    99
	TInt n = iEntries.Count();
sl@0
   100
	for (TInt i = 0; i < n; ++i)
sl@0
   101
		{
sl@0
   102
		if (!aSessionHandle || aSessionHandle == iEntries[i]->SessionHandle())
sl@0
   103
			iEntries[i]->CloseFileStore();
sl@0
   104
		}
sl@0
   105
 	}
sl@0
   106
sl@0
   107
CFbTopStreamIdCache::RCacheEntry* CFbTopStreamIdCache::AddCacheEntryL(const TDesC& aFilename, TUint aFileOffset)
sl@0
   108
	{
sl@0
   109
	RCacheEntry *entry;
sl@0
   110
	TInt n = iEntries.Count();
sl@0
   111
	if (n < iMaxCacheFilestores)
sl@0
   112
		{
sl@0
   113
		TInt size = RCacheEntry::KBaseSize + (iForwardCacheSize + iBackwardCacheSize) * sizeof(TStreamId);
sl@0
   114
		if (iBuffer == NULL)
sl@0
   115
			iBuffer = static_cast<TUint8*>(User::AllocL(iMaxCacheFilestores * size));
sl@0
   116
		entry = reinterpret_cast<RCacheEntry*>(iBuffer + n * size);
sl@0
   117
		}
sl@0
   118
	else
sl@0
   119
		{
sl@0
   120
		entry = iEntries[--n];
sl@0
   121
		entry->CloseFileStore();
sl@0
   122
		iEntries.Remove(n);
sl@0
   123
		}
sl@0
   124
	iEntries.InsertL(entry, 0);
sl@0
   125
	return new(entry) RCacheEntry(aFilename, aFileOffset);
sl@0
   126
	}
sl@0
   127
sl@0
   128
CFbTopStreamIdCache::RCacheEntry* CFbTopStreamIdCache::FindCacheEntry(const TDesC& aFilename, TUint aFileOffset)
sl@0
   129
	{
sl@0
   130
	TInt n = iEntries.Count();
sl@0
   131
	for (TInt i = 0; i < n; ++i)
sl@0
   132
		{
sl@0
   133
		RCacheEntry *entry = iEntries[i];
sl@0
   134
		if (entry->SameFile(aFilename, aFileOffset))
sl@0
   135
			{
sl@0
   136
			if (i > 0)
sl@0
   137
				{
sl@0
   138
				iEntries.Remove(i); // Keep least-recently-used order
sl@0
   139
				iEntries.Insert(entry, 0); // Cannot fail
sl@0
   140
				}
sl@0
   141
			return entry;
sl@0
   142
			}
sl@0
   143
		}
sl@0
   144
	return NULL;
sl@0
   145
	}
sl@0
   146
sl@0
   147
sl@0
   148
const TInt CFbTopStreamIdCache::RCacheEntry::KBaseSize = _FOFF(CFbTopStreamIdCache::RCacheEntry, iStreamIdCache);
sl@0
   149
sl@0
   150
sl@0
   151
CFbTopStreamIdCache::RCacheEntry::RCacheEntry(const TDesC& aFilename, TUint aFileOffset)
sl@0
   152
:	iFilename(aFilename),
sl@0
   153
	iFileOffset(aFileOffset),
sl@0
   154
	iFilestore(NULL),
sl@0
   155
	iLastId(KErrNotFound),
sl@0
   156
	iStreamIdCount(0),
sl@0
   157
	iSessionHandle(0)
sl@0
   158
	{
sl@0
   159
	}
sl@0
   160
sl@0
   161
TBool CFbTopStreamIdCache::RCacheEntry::SameFile(const TDesC& aFilename, TUint aFileOffset)
sl@0
   162
	{
sl@0
   163
	return !aFilename.Compare(iFilename) && aFileOffset == iFileOffset;
sl@0
   164
	}
sl@0
   165
sl@0
   166
TStreamId CFbTopStreamIdCache::RCacheEntry::GetStreamIdL(TInt32 aId, TInt aForwardSize, TInt aBackwardSize)
sl@0
   167
	{
sl@0
   168
	if (iLastId >= 0 && aId >= iLastId - aBackwardSize && aId < iLastId + aForwardSize)
sl@0
   169
		{
sl@0
   170
		TInt startindex = iLastId < aBackwardSize ? 0 : iLastId - aBackwardSize;
sl@0
   171
		// ensure aId exists in the MBM file
sl@0
   172
		// cache size previously set using the number of bitmaps
sl@0
   173
		if (aId - startindex >= iStreamIdCount)
sl@0
   174
			User::Leave(KErrEof);
sl@0
   175
		return iStreamIdCache[aId - startindex];
sl@0
   176
		}
sl@0
   177
	//Flush the cache array
sl@0
   178
	iLastId = KErrNotFound;
sl@0
   179
	iStreamIdCount = 0;
sl@0
   180
sl@0
   181
	//Extracting the header stream parameters numbitmaps and the stream ids
sl@0
   182
	TStreamId bmpstreamid(iFilestore->Root().Value() + iFileOffset);
sl@0
   183
	RStoreReadStream readstream;
sl@0
   184
	readstream.OpenLC(*iFilestore, bmpstreamid);
sl@0
   185
	TInt numbitmaps = readstream.ReadInt32L();
sl@0
   186
	if (aId >= numbitmaps)
sl@0
   187
		User::Leave(KErrEof);
sl@0
   188
	TInt endcount = aId + aForwardSize;
sl@0
   189
	//if endcount is greater than the numbitmaps we need to truncate it so we
sl@0
   190
	//never overread and cause panic.
sl@0
   191
	if (endcount > numbitmaps)
sl@0
   192
		endcount = numbitmaps;
sl@0
   193
	for (TInt count = 0; count < endcount; ++count)
sl@0
   194
		{
sl@0
   195
		bmpstreamid.InternalizeL(readstream);
sl@0
   196
		bmpstreamid=TStreamId(bmpstreamid.Value() + iFileOffset);
sl@0
   197
		if (count >= aId - aBackwardSize)
sl@0
   198
			iStreamIdCache[iStreamIdCount++] = bmpstreamid;
sl@0
   199
		}
sl@0
   200
	//get the stream id of the requested bitmap id
sl@0
   201
	TInt startindex = aId < aBackwardSize ? 0 : aId - aBackwardSize;
sl@0
   202
	bmpstreamid = iStreamIdCache[aId - startindex];
sl@0
   203
	CleanupStack::PopAndDestroy();
sl@0
   204
	// iLastId is updated just before returning to ensure that for error cases
sl@0
   205
	// the cache is not used in subsequent calls to this method.
sl@0
   206
	iLastId = aId;
sl@0
   207
	return bmpstreamid;
sl@0
   208
	}
sl@0
   209
sl@0
   210
CShiftedFileStore* CFbTopStreamIdCache::RCacheEntry::FileStore()
sl@0
   211
	{
sl@0
   212
	return iFilestore;
sl@0
   213
	}
sl@0
   214
sl@0
   215
TInt CFbTopStreamIdCache::RCacheEntry::SessionHandle() const
sl@0
   216
	{
sl@0
   217
	return iSessionHandle;
sl@0
   218
	}
sl@0
   219
sl@0
   220
void CFbTopStreamIdCache::RCacheEntry::CloseFileStore()
sl@0
   221
	{
sl@0
   222
	delete iFilestore;
sl@0
   223
	iFilestore = NULL;
sl@0
   224
	iSessionHandle = 0;
sl@0
   225
 	}
sl@0
   226
sl@0
   227
/**
sl@0
   228
It creates a file store if is not there i.e. if iFileStore is NULL.
sl@0
   229
sl@0
   230
@param  aFile the mbm or rsc file handle
sl@0
   231
@param  aSessionHandle the associated client session handle
sl@0
   232
*/
sl@0
   233
void CFbTopStreamIdCache::RCacheEntry::CreateFileStoreL(RFile& aFile, TInt aSessionHandle)
sl@0
   234
	{
sl@0
   235
	if (iFilestore == NULL)
sl@0
   236
		{
sl@0
   237
		iFilestore = CShiftedFileStore::FromL(aFile, iFileOffset);
sl@0
   238
		iSessionHandle = aSessionHandle;
sl@0
   239
		}
sl@0
   240
	}
sl@0
   241
sl@0
   242
/**
sl@0
   243
It creates a file store if is not there i.e. if iFileStore is NULL.
sl@0
   244
sl@0
   245
@param  aFs the associated file session handle
sl@0
   246
@param  aFileName the mbm or rsc file name
sl@0
   247
@param  aSessionHandle the associated client session handle
sl@0
   248
*/
sl@0
   249
void CFbTopStreamIdCache::RCacheEntry::CreateFileStoreL(RFs& aFs, const TDesC& aFileName, TInt aSessionHandle)
sl@0
   250
	{
sl@0
   251
	if (iFilestore == NULL)
sl@0
   252
		{
sl@0
   253
		RFile file;
sl@0
   254
		User::LeaveIfError(file.Open(aFs,aFileName,EFileShareReadersOnly));
sl@0
   255
		iFilestore = CShiftedFileStore::FromL(file, iFileOffset);
sl@0
   256
		iSessionHandle = aSessionHandle;
sl@0
   257
		}
sl@0
   258
	}