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 + }