First public contribution.
1 // Copyright (c) 2004-2009 Nokia Corporation and/or its subsidiary(-ies).
2 // All rights reserved.
3 // This component and the accompanying materials are made available
4 // under the terms of "Eclipse Public License v1.0"
5 // which accompanies this distribution, and is available
6 // at the URL "http://www.eclipse.org/legal/epl-v10.html".
8 // Initial Contributors:
9 // Nokia Corporation - initial contribution.
14 // This file holds the class methods for the CFbTopMBMCache
22 //Constructor for CFbTopMBMCache objects with both forward and backward cache size
23 //The forward(backward) cache size determines the number of stream ids after(before)
24 //the current loaded bitmap ids to be stored in the cache
25 //e.g Loading a bitmap with id=20 from a 40 bitmaps mbm file will load the cache(10,10)
26 //with stream ids from 30-39(10 backward) and 40-49(10 forward)
27 CFbTopStreamIdCache::CFbTopStreamIdCache(TInt aForwardSize, TInt aBackwardSize, TInt aMaxFilestores)
29 iEntries(aMaxFilestores),
30 iForwardCacheSize(aForwardSize),
31 iBackwardCacheSize(aBackwardSize),
32 iMaxCacheFilestores(aMaxFilestores)
37 //Destructor of CFbTopMBMCache objects
38 CFbTopStreamIdCache::~CFbTopStreamIdCache()
43 //Function to reset all the internal state of the class
44 void CFbTopStreamIdCache::FlushCache()
53 //Function to get the most recently used filestore stored in the cache
54 CShiftedFileStore* CFbTopStreamIdCache::MruFileStore()
56 return iEntries[0]->FileStore();
59 //Function to get the stream id for a bitmap id from a mbm file with certain offset.
60 //It also fills up the cache with the stream ids for different bitmap from the same
61 //mbm file and the number of stream ids stored depend on the initial setting of the
62 //cache size. Also associates each resource with a client handle to improve the
63 //performance of cleaning up.
64 TStreamId CFbTopStreamIdCache::GetStreamIdL(RFile& aFile,const TDesC& aFilename,TInt32 aId,TUint aFileOffset, TInt aSessionHandle)
70 RCacheEntry *entry = FindCacheEntry(aFilename, aFileOffset);
73 entry = AddCacheEntryL(aFilename, aFileOffset);
75 entry->CreateFileStoreL(aFile, aSessionHandle);
76 return entry->GetStreamIdL(aId, iForwardCacheSize, iBackwardCacheSize);
80 The overloaded version of GetStreamIdL which works with file session instead of file handle.
82 TStreamId CFbTopStreamIdCache::GetStreamIdL(RFs& aFs, const TDesC& aFileName,TInt32 aId,TUint aFileOffset, TInt aSessionHandle)
88 RCacheEntry *entry = FindCacheEntry(aFileName, aFileOffset);
91 entry = AddCacheEntryL(aFileName, aFileOffset);
93 entry->CreateFileStoreL(aFs, aFileName, aSessionHandle);
94 return entry->GetStreamIdL(aId, iForwardCacheSize, iBackwardCacheSize);
97 void CFbTopStreamIdCache::CloseFileStores(TInt aSessionHandle)
99 TInt n = iEntries.Count();
100 for (TInt i = 0; i < n; ++i)
102 if (!aSessionHandle || aSessionHandle == iEntries[i]->SessionHandle())
103 iEntries[i]->CloseFileStore();
107 CFbTopStreamIdCache::RCacheEntry* CFbTopStreamIdCache::AddCacheEntryL(const TDesC& aFilename, TUint aFileOffset)
110 TInt n = iEntries.Count();
111 if (n < iMaxCacheFilestores)
113 TInt size = RCacheEntry::KBaseSize + (iForwardCacheSize + iBackwardCacheSize) * sizeof(TStreamId);
115 iBuffer = static_cast<TUint8*>(User::AllocL(iMaxCacheFilestores * size));
116 entry = reinterpret_cast<RCacheEntry*>(iBuffer + n * size);
120 entry = iEntries[--n];
121 entry->CloseFileStore();
124 iEntries.InsertL(entry, 0);
125 return new(entry) RCacheEntry(aFilename, aFileOffset);
128 CFbTopStreamIdCache::RCacheEntry* CFbTopStreamIdCache::FindCacheEntry(const TDesC& aFilename, TUint aFileOffset)
130 TInt n = iEntries.Count();
131 for (TInt i = 0; i < n; ++i)
133 RCacheEntry *entry = iEntries[i];
134 if (entry->SameFile(aFilename, aFileOffset))
138 iEntries.Remove(i); // Keep least-recently-used order
139 iEntries.Insert(entry, 0); // Cannot fail
148 const TInt CFbTopStreamIdCache::RCacheEntry::KBaseSize = _FOFF(CFbTopStreamIdCache::RCacheEntry, iStreamIdCache);
151 CFbTopStreamIdCache::RCacheEntry::RCacheEntry(const TDesC& aFilename, TUint aFileOffset)
152 : iFilename(aFilename),
153 iFileOffset(aFileOffset),
155 iLastId(KErrNotFound),
161 TBool CFbTopStreamIdCache::RCacheEntry::SameFile(const TDesC& aFilename, TUint aFileOffset)
163 return !aFilename.Compare(iFilename) && aFileOffset == iFileOffset;
166 TStreamId CFbTopStreamIdCache::RCacheEntry::GetStreamIdL(TInt32 aId, TInt aForwardSize, TInt aBackwardSize)
168 if (iLastId >= 0 && aId >= iLastId - aBackwardSize && aId < iLastId + aForwardSize)
170 TInt startindex = iLastId < aBackwardSize ? 0 : iLastId - aBackwardSize;
171 // ensure aId exists in the MBM file
172 // cache size previously set using the number of bitmaps
173 if (aId - startindex >= iStreamIdCount)
174 User::Leave(KErrEof);
175 return iStreamIdCache[aId - startindex];
177 //Flush the cache array
178 iLastId = KErrNotFound;
181 //Extracting the header stream parameters numbitmaps and the stream ids
182 TStreamId bmpstreamid(iFilestore->Root().Value() + iFileOffset);
183 RStoreReadStream readstream;
184 readstream.OpenLC(*iFilestore, bmpstreamid);
185 TInt numbitmaps = readstream.ReadInt32L();
186 if (aId >= numbitmaps)
187 User::Leave(KErrEof);
188 TInt endcount = aId + aForwardSize;
189 //if endcount is greater than the numbitmaps we need to truncate it so we
190 //never overread and cause panic.
191 if (endcount > numbitmaps)
192 endcount = numbitmaps;
193 for (TInt count = 0; count < endcount; ++count)
195 bmpstreamid.InternalizeL(readstream);
196 bmpstreamid=TStreamId(bmpstreamid.Value() + iFileOffset);
197 if (count >= aId - aBackwardSize)
198 iStreamIdCache[iStreamIdCount++] = bmpstreamid;
200 //get the stream id of the requested bitmap id
201 TInt startindex = aId < aBackwardSize ? 0 : aId - aBackwardSize;
202 bmpstreamid = iStreamIdCache[aId - startindex];
203 CleanupStack::PopAndDestroy();
204 // iLastId is updated just before returning to ensure that for error cases
205 // the cache is not used in subsequent calls to this method.
210 CShiftedFileStore* CFbTopStreamIdCache::RCacheEntry::FileStore()
215 TInt CFbTopStreamIdCache::RCacheEntry::SessionHandle() const
217 return iSessionHandle;
220 void CFbTopStreamIdCache::RCacheEntry::CloseFileStore()
228 It creates a file store if is not there i.e. if iFileStore is NULL.
230 @param aFile the mbm or rsc file handle
231 @param aSessionHandle the associated client session handle
233 void CFbTopStreamIdCache::RCacheEntry::CreateFileStoreL(RFile& aFile, TInt aSessionHandle)
235 if (iFilestore == NULL)
237 iFilestore = CShiftedFileStore::FromL(aFile, iFileOffset);
238 iSessionHandle = aSessionHandle;
243 It creates a file store if is not there i.e. if iFileStore is NULL.
245 @param aFs the associated file session handle
246 @param aFileName the mbm or rsc file name
247 @param aSessionHandle the associated client session handle
249 void CFbTopStreamIdCache::RCacheEntry::CreateFileStoreL(RFs& aFs, const TDesC& aFileName, TInt aSessionHandle)
251 if (iFilestore == NULL)
254 User::LeaveIfError(file.Open(aFs,aFileName,EFileShareReadersOnly));
255 iFilestore = CShiftedFileStore::FromL(file, iFileOffset);
256 iSessionHandle = aSessionHandle;