os/graphics/fbs/fontandbitmapserver/sfbs/FBSMBMC.CPP
changeset 0 bde4ae8d615e
     1.1 --- /dev/null	Thu Jan 01 00:00:00 1970 +0000
     1.2 +++ b/os/graphics/fbs/fontandbitmapserver/sfbs/FBSMBMC.CPP	Fri Jun 15 03:10:57 2012 +0200
     1.3 @@ -0,0 +1,258 @@
     1.4 +// Copyright (c) 2004-2009 Nokia Corporation and/or its subsidiary(-ies).
     1.5 +// All rights reserved.
     1.6 +// This component and the accompanying materials are made available
     1.7 +// under the terms of "Eclipse Public License v1.0"
     1.8 +// which accompanies this distribution, and is available
     1.9 +// at the URL "http://www.eclipse.org/legal/epl-v10.html".
    1.10 +//
    1.11 +// Initial Contributors:
    1.12 +// Nokia Corporation - initial contribution.
    1.13 +//
    1.14 +// Contributors:
    1.15 +//
    1.16 +// Description:
    1.17 +// This file holds the class methods for the CFbTopMBMCache
    1.18 +// 
    1.19 +//
    1.20 +
    1.21 +#include "FBSMBMC.H"
    1.22 +
    1.23 +
    1.24 +//
    1.25 +//Constructor for CFbTopMBMCache objects with both forward and backward cache size
    1.26 +//The forward(backward) cache size determines the number of stream ids after(before)
    1.27 +//the current loaded bitmap ids to be stored in the cache
    1.28 +//e.g Loading a bitmap with id=20 from a 40 bitmaps mbm file will load the cache(10,10)
    1.29 +//with stream ids from 30-39(10 backward) and 40-49(10 forward)
    1.30 +CFbTopStreamIdCache::CFbTopStreamIdCache(TInt aForwardSize, TInt aBackwardSize, TInt aMaxFilestores)
    1.31 +	:CBase(),
    1.32 +	iEntries(aMaxFilestores),
    1.33 +	iForwardCacheSize(aForwardSize),
    1.34 +	iBackwardCacheSize(aBackwardSize),
    1.35 +	iMaxCacheFilestores(aMaxFilestores)
    1.36 +	{
    1.37 +	}
    1.38 +
    1.39 +//
    1.40 +//Destructor of CFbTopMBMCache objects
    1.41 +CFbTopStreamIdCache::~CFbTopStreamIdCache()
    1.42 +	{
    1.43 +	FlushCache();
    1.44 +	}
    1.45 +
    1.46 +//Function to reset all the internal state of the class
    1.47 +void CFbTopStreamIdCache::FlushCache()
    1.48 +	{
    1.49 +	CloseFileStores();
    1.50 +	iEntries.Reset();
    1.51 +	User::Free(iBuffer);
    1.52 +	iBuffer = NULL;
    1.53 +	}
    1.54 +
    1.55 +
    1.56 +//Function to get the most recently used filestore stored in the cache
    1.57 +CShiftedFileStore* CFbTopStreamIdCache::MruFileStore()
    1.58 +	{
    1.59 +	return iEntries[0]->FileStore();
    1.60 +	}
    1.61 +
    1.62 +//Function to get the stream id for a bitmap id from a mbm file with certain offset.
    1.63 +//It also fills up the cache with the stream ids for different bitmap from the same
    1.64 +//mbm file and the number of stream ids stored depend on the initial setting of the
    1.65 +//cache size. Also associates each resource with a client handle to improve the
    1.66 +//performance of cleaning up.
    1.67 +TStreamId CFbTopStreamIdCache::GetStreamIdL(RFile& aFile,const TDesC& aFilename,TInt32 aId,TUint aFileOffset, TInt aSessionHandle)
    1.68 +	{
    1.69 +	if (aId < 0)
    1.70 +		{
    1.71 +		User::Leave(KErrEof);
    1.72 +		}
    1.73 +	RCacheEntry *entry = FindCacheEntry(aFilename, aFileOffset);
    1.74 +	if (entry == NULL)
    1.75 +		{
    1.76 +		entry = AddCacheEntryL(aFilename, aFileOffset);
    1.77 +		}
    1.78 +	entry->CreateFileStoreL(aFile, aSessionHandle);
    1.79 +	return entry->GetStreamIdL(aId, iForwardCacheSize, iBackwardCacheSize);
    1.80 +	}
    1.81 +
    1.82 +/**
    1.83 +The overloaded version of GetStreamIdL which works with file session instead of file handle.
    1.84 +*/
    1.85 +TStreamId CFbTopStreamIdCache::GetStreamIdL(RFs& aFs, const TDesC& aFileName,TInt32 aId,TUint aFileOffset, TInt aSessionHandle)
    1.86 +	{
    1.87 +	if (aId < 0)
    1.88 +		{
    1.89 +		User::Leave(KErrEof);
    1.90 +		}
    1.91 +	RCacheEntry *entry = FindCacheEntry(aFileName, aFileOffset);
    1.92 +	if (entry == NULL)
    1.93 +		{
    1.94 +		entry = AddCacheEntryL(aFileName, aFileOffset);
    1.95 +		}
    1.96 +	entry->CreateFileStoreL(aFs, aFileName, aSessionHandle);
    1.97 +	return entry->GetStreamIdL(aId, iForwardCacheSize, iBackwardCacheSize);
    1.98 +	}
    1.99 +
   1.100 +void CFbTopStreamIdCache::CloseFileStores(TInt aSessionHandle)
   1.101 +	{
   1.102 +	TInt n = iEntries.Count();
   1.103 +	for (TInt i = 0; i < n; ++i)
   1.104 +		{
   1.105 +		if (!aSessionHandle || aSessionHandle == iEntries[i]->SessionHandle())
   1.106 +			iEntries[i]->CloseFileStore();
   1.107 +		}
   1.108 + 	}
   1.109 +
   1.110 +CFbTopStreamIdCache::RCacheEntry* CFbTopStreamIdCache::AddCacheEntryL(const TDesC& aFilename, TUint aFileOffset)
   1.111 +	{
   1.112 +	RCacheEntry *entry;
   1.113 +	TInt n = iEntries.Count();
   1.114 +	if (n < iMaxCacheFilestores)
   1.115 +		{
   1.116 +		TInt size = RCacheEntry::KBaseSize + (iForwardCacheSize + iBackwardCacheSize) * sizeof(TStreamId);
   1.117 +		if (iBuffer == NULL)
   1.118 +			iBuffer = static_cast<TUint8*>(User::AllocL(iMaxCacheFilestores * size));
   1.119 +		entry = reinterpret_cast<RCacheEntry*>(iBuffer + n * size);
   1.120 +		}
   1.121 +	else
   1.122 +		{
   1.123 +		entry = iEntries[--n];
   1.124 +		entry->CloseFileStore();
   1.125 +		iEntries.Remove(n);
   1.126 +		}
   1.127 +	iEntries.InsertL(entry, 0);
   1.128 +	return new(entry) RCacheEntry(aFilename, aFileOffset);
   1.129 +	}
   1.130 +
   1.131 +CFbTopStreamIdCache::RCacheEntry* CFbTopStreamIdCache::FindCacheEntry(const TDesC& aFilename, TUint aFileOffset)
   1.132 +	{
   1.133 +	TInt n = iEntries.Count();
   1.134 +	for (TInt i = 0; i < n; ++i)
   1.135 +		{
   1.136 +		RCacheEntry *entry = iEntries[i];
   1.137 +		if (entry->SameFile(aFilename, aFileOffset))
   1.138 +			{
   1.139 +			if (i > 0)
   1.140 +				{
   1.141 +				iEntries.Remove(i); // Keep least-recently-used order
   1.142 +				iEntries.Insert(entry, 0); // Cannot fail
   1.143 +				}
   1.144 +			return entry;
   1.145 +			}
   1.146 +		}
   1.147 +	return NULL;
   1.148 +	}
   1.149 +
   1.150 +
   1.151 +const TInt CFbTopStreamIdCache::RCacheEntry::KBaseSize = _FOFF(CFbTopStreamIdCache::RCacheEntry, iStreamIdCache);
   1.152 +
   1.153 +
   1.154 +CFbTopStreamIdCache::RCacheEntry::RCacheEntry(const TDesC& aFilename, TUint aFileOffset)
   1.155 +:	iFilename(aFilename),
   1.156 +	iFileOffset(aFileOffset),
   1.157 +	iFilestore(NULL),
   1.158 +	iLastId(KErrNotFound),
   1.159 +	iStreamIdCount(0),
   1.160 +	iSessionHandle(0)
   1.161 +	{
   1.162 +	}
   1.163 +
   1.164 +TBool CFbTopStreamIdCache::RCacheEntry::SameFile(const TDesC& aFilename, TUint aFileOffset)
   1.165 +	{
   1.166 +	return !aFilename.Compare(iFilename) && aFileOffset == iFileOffset;
   1.167 +	}
   1.168 +
   1.169 +TStreamId CFbTopStreamIdCache::RCacheEntry::GetStreamIdL(TInt32 aId, TInt aForwardSize, TInt aBackwardSize)
   1.170 +	{
   1.171 +	if (iLastId >= 0 && aId >= iLastId - aBackwardSize && aId < iLastId + aForwardSize)
   1.172 +		{
   1.173 +		TInt startindex = iLastId < aBackwardSize ? 0 : iLastId - aBackwardSize;
   1.174 +		// ensure aId exists in the MBM file
   1.175 +		// cache size previously set using the number of bitmaps
   1.176 +		if (aId - startindex >= iStreamIdCount)
   1.177 +			User::Leave(KErrEof);
   1.178 +		return iStreamIdCache[aId - startindex];
   1.179 +		}
   1.180 +	//Flush the cache array
   1.181 +	iLastId = KErrNotFound;
   1.182 +	iStreamIdCount = 0;
   1.183 +
   1.184 +	//Extracting the header stream parameters numbitmaps and the stream ids
   1.185 +	TStreamId bmpstreamid(iFilestore->Root().Value() + iFileOffset);
   1.186 +	RStoreReadStream readstream;
   1.187 +	readstream.OpenLC(*iFilestore, bmpstreamid);
   1.188 +	TInt numbitmaps = readstream.ReadInt32L();
   1.189 +	if (aId >= numbitmaps)
   1.190 +		User::Leave(KErrEof);
   1.191 +	TInt endcount = aId + aForwardSize;
   1.192 +	//if endcount is greater than the numbitmaps we need to truncate it so we
   1.193 +	//never overread and cause panic.
   1.194 +	if (endcount > numbitmaps)
   1.195 +		endcount = numbitmaps;
   1.196 +	for (TInt count = 0; count < endcount; ++count)
   1.197 +		{
   1.198 +		bmpstreamid.InternalizeL(readstream);
   1.199 +		bmpstreamid=TStreamId(bmpstreamid.Value() + iFileOffset);
   1.200 +		if (count >= aId - aBackwardSize)
   1.201 +			iStreamIdCache[iStreamIdCount++] = bmpstreamid;
   1.202 +		}
   1.203 +	//get the stream id of the requested bitmap id
   1.204 +	TInt startindex = aId < aBackwardSize ? 0 : aId - aBackwardSize;
   1.205 +	bmpstreamid = iStreamIdCache[aId - startindex];
   1.206 +	CleanupStack::PopAndDestroy();
   1.207 +	// iLastId is updated just before returning to ensure that for error cases
   1.208 +	// the cache is not used in subsequent calls to this method.
   1.209 +	iLastId = aId;
   1.210 +	return bmpstreamid;
   1.211 +	}
   1.212 +
   1.213 +CShiftedFileStore* CFbTopStreamIdCache::RCacheEntry::FileStore()
   1.214 +	{
   1.215 +	return iFilestore;
   1.216 +	}
   1.217 +
   1.218 +TInt CFbTopStreamIdCache::RCacheEntry::SessionHandle() const
   1.219 +	{
   1.220 +	return iSessionHandle;
   1.221 +	}
   1.222 +
   1.223 +void CFbTopStreamIdCache::RCacheEntry::CloseFileStore()
   1.224 +	{
   1.225 +	delete iFilestore;
   1.226 +	iFilestore = NULL;
   1.227 +	iSessionHandle = 0;
   1.228 + 	}
   1.229 +
   1.230 +/**
   1.231 +It creates a file store if is not there i.e. if iFileStore is NULL.
   1.232 +
   1.233 +@param  aFile the mbm or rsc file handle
   1.234 +@param  aSessionHandle the associated client session handle
   1.235 +*/
   1.236 +void CFbTopStreamIdCache::RCacheEntry::CreateFileStoreL(RFile& aFile, TInt aSessionHandle)
   1.237 +	{
   1.238 +	if (iFilestore == NULL)
   1.239 +		{
   1.240 +		iFilestore = CShiftedFileStore::FromL(aFile, iFileOffset);
   1.241 +		iSessionHandle = aSessionHandle;
   1.242 +		}
   1.243 +	}
   1.244 +
   1.245 +/**
   1.246 +It creates a file store if is not there i.e. if iFileStore is NULL.
   1.247 +
   1.248 +@param  aFs the associated file session handle
   1.249 +@param  aFileName the mbm or rsc file name
   1.250 +@param  aSessionHandle the associated client session handle
   1.251 +*/
   1.252 +void CFbTopStreamIdCache::RCacheEntry::CreateFileStoreL(RFs& aFs, const TDesC& aFileName, TInt aSessionHandle)
   1.253 +	{
   1.254 +	if (iFilestore == NULL)
   1.255 +		{
   1.256 +		RFile file;
   1.257 +		User::LeaveIfError(file.Open(aFs,aFileName,EFileShareReadersOnly));
   1.258 +		iFilestore = CShiftedFileStore::FromL(file, iFileOffset);
   1.259 +		iSessionHandle = aSessionHandle;
   1.260 +		}
   1.261 +	}