fbs/fontandbitmapserver/sfbs/FBSMBMC.CPP
changeset 0 5d03bc08d59c
equal deleted inserted replaced
-1:000000000000 0:5d03bc08d59c
       
     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".
       
     7 //
       
     8 // Initial Contributors:
       
     9 // Nokia Corporation - initial contribution.
       
    10 //
       
    11 // Contributors:
       
    12 //
       
    13 // Description:
       
    14 // This file holds the class methods for the CFbTopMBMCache
       
    15 // 
       
    16 //
       
    17 
       
    18 #include "FBSMBMC.H"
       
    19 
       
    20 
       
    21 //
       
    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)
       
    28 	:CBase(),
       
    29 	iEntries(aMaxFilestores),
       
    30 	iForwardCacheSize(aForwardSize),
       
    31 	iBackwardCacheSize(aBackwardSize),
       
    32 	iMaxCacheFilestores(aMaxFilestores)
       
    33 	{
       
    34 	}
       
    35 
       
    36 //
       
    37 //Destructor of CFbTopMBMCache objects
       
    38 CFbTopStreamIdCache::~CFbTopStreamIdCache()
       
    39 	{
       
    40 	FlushCache();
       
    41 	}
       
    42 
       
    43 //Function to reset all the internal state of the class
       
    44 void CFbTopStreamIdCache::FlushCache()
       
    45 	{
       
    46 	CloseFileStores();
       
    47 	iEntries.Reset();
       
    48 	User::Free(iBuffer);
       
    49 	iBuffer = NULL;
       
    50 	}
       
    51 
       
    52 
       
    53 //Function to get the most recently used filestore stored in the cache
       
    54 CShiftedFileStore* CFbTopStreamIdCache::MruFileStore()
       
    55 	{
       
    56 	return iEntries[0]->FileStore();
       
    57 	}
       
    58 
       
    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)
       
    65 	{
       
    66 	if (aId < 0)
       
    67 		{
       
    68 		User::Leave(KErrEof);
       
    69 		}
       
    70 	RCacheEntry *entry = FindCacheEntry(aFilename, aFileOffset);
       
    71 	if (entry == NULL)
       
    72 		{
       
    73 		entry = AddCacheEntryL(aFilename, aFileOffset);
       
    74 		}
       
    75 	entry->CreateFileStoreL(aFile, aSessionHandle);
       
    76 	return entry->GetStreamIdL(aId, iForwardCacheSize, iBackwardCacheSize);
       
    77 	}
       
    78 
       
    79 /**
       
    80 The overloaded version of GetStreamIdL which works with file session instead of file handle.
       
    81 */
       
    82 TStreamId CFbTopStreamIdCache::GetStreamIdL(RFs& aFs, const TDesC& aFileName,TInt32 aId,TUint aFileOffset, TInt aSessionHandle)
       
    83 	{
       
    84 	if (aId < 0)
       
    85 		{
       
    86 		User::Leave(KErrEof);
       
    87 		}
       
    88 	RCacheEntry *entry = FindCacheEntry(aFileName, aFileOffset);
       
    89 	if (entry == NULL)
       
    90 		{
       
    91 		entry = AddCacheEntryL(aFileName, aFileOffset);
       
    92 		}
       
    93 	entry->CreateFileStoreL(aFs, aFileName, aSessionHandle);
       
    94 	return entry->GetStreamIdL(aId, iForwardCacheSize, iBackwardCacheSize);
       
    95 	}
       
    96 
       
    97 void CFbTopStreamIdCache::CloseFileStores(TInt aSessionHandle)
       
    98 	{
       
    99 	TInt n = iEntries.Count();
       
   100 	for (TInt i = 0; i < n; ++i)
       
   101 		{
       
   102 		if (!aSessionHandle || aSessionHandle == iEntries[i]->SessionHandle())
       
   103 			iEntries[i]->CloseFileStore();
       
   104 		}
       
   105  	}
       
   106 
       
   107 CFbTopStreamIdCache::RCacheEntry* CFbTopStreamIdCache::AddCacheEntryL(const TDesC& aFilename, TUint aFileOffset)
       
   108 	{
       
   109 	RCacheEntry *entry;
       
   110 	TInt n = iEntries.Count();
       
   111 	if (n < iMaxCacheFilestores)
       
   112 		{
       
   113 		TInt size = RCacheEntry::KBaseSize + (iForwardCacheSize + iBackwardCacheSize) * sizeof(TStreamId);
       
   114 		if (iBuffer == NULL)
       
   115 			iBuffer = static_cast<TUint8*>(User::AllocL(iMaxCacheFilestores * size));
       
   116 		entry = reinterpret_cast<RCacheEntry*>(iBuffer + n * size);
       
   117 		}
       
   118 	else
       
   119 		{
       
   120 		entry = iEntries[--n];
       
   121 		entry->CloseFileStore();
       
   122 		iEntries.Remove(n);
       
   123 		}
       
   124 	iEntries.InsertL(entry, 0);
       
   125 	return new(entry) RCacheEntry(aFilename, aFileOffset);
       
   126 	}
       
   127 
       
   128 CFbTopStreamIdCache::RCacheEntry* CFbTopStreamIdCache::FindCacheEntry(const TDesC& aFilename, TUint aFileOffset)
       
   129 	{
       
   130 	TInt n = iEntries.Count();
       
   131 	for (TInt i = 0; i < n; ++i)
       
   132 		{
       
   133 		RCacheEntry *entry = iEntries[i];
       
   134 		if (entry->SameFile(aFilename, aFileOffset))
       
   135 			{
       
   136 			if (i > 0)
       
   137 				{
       
   138 				iEntries.Remove(i); // Keep least-recently-used order
       
   139 				iEntries.Insert(entry, 0); // Cannot fail
       
   140 				}
       
   141 			return entry;
       
   142 			}
       
   143 		}
       
   144 	return NULL;
       
   145 	}
       
   146 
       
   147 
       
   148 const TInt CFbTopStreamIdCache::RCacheEntry::KBaseSize = _FOFF(CFbTopStreamIdCache::RCacheEntry, iStreamIdCache);
       
   149 
       
   150 
       
   151 CFbTopStreamIdCache::RCacheEntry::RCacheEntry(const TDesC& aFilename, TUint aFileOffset)
       
   152 :	iFilename(aFilename),
       
   153 	iFileOffset(aFileOffset),
       
   154 	iFilestore(NULL),
       
   155 	iLastId(KErrNotFound),
       
   156 	iStreamIdCount(0),
       
   157 	iSessionHandle(0)
       
   158 	{
       
   159 	}
       
   160 
       
   161 TBool CFbTopStreamIdCache::RCacheEntry::SameFile(const TDesC& aFilename, TUint aFileOffset)
       
   162 	{
       
   163 	return !aFilename.Compare(iFilename) && aFileOffset == iFileOffset;
       
   164 	}
       
   165 
       
   166 TStreamId CFbTopStreamIdCache::RCacheEntry::GetStreamIdL(TInt32 aId, TInt aForwardSize, TInt aBackwardSize)
       
   167 	{
       
   168 	if (iLastId >= 0 && aId >= iLastId - aBackwardSize && aId < iLastId + aForwardSize)
       
   169 		{
       
   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];
       
   176 		}
       
   177 	//Flush the cache array
       
   178 	iLastId = KErrNotFound;
       
   179 	iStreamIdCount = 0;
       
   180 
       
   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)
       
   194 		{
       
   195 		bmpstreamid.InternalizeL(readstream);
       
   196 		bmpstreamid=TStreamId(bmpstreamid.Value() + iFileOffset);
       
   197 		if (count >= aId - aBackwardSize)
       
   198 			iStreamIdCache[iStreamIdCount++] = bmpstreamid;
       
   199 		}
       
   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.
       
   206 	iLastId = aId;
       
   207 	return bmpstreamid;
       
   208 	}
       
   209 
       
   210 CShiftedFileStore* CFbTopStreamIdCache::RCacheEntry::FileStore()
       
   211 	{
       
   212 	return iFilestore;
       
   213 	}
       
   214 
       
   215 TInt CFbTopStreamIdCache::RCacheEntry::SessionHandle() const
       
   216 	{
       
   217 	return iSessionHandle;
       
   218 	}
       
   219 
       
   220 void CFbTopStreamIdCache::RCacheEntry::CloseFileStore()
       
   221 	{
       
   222 	delete iFilestore;
       
   223 	iFilestore = NULL;
       
   224 	iSessionHandle = 0;
       
   225  	}
       
   226 
       
   227 /**
       
   228 It creates a file store if is not there i.e. if iFileStore is NULL.
       
   229 
       
   230 @param  aFile the mbm or rsc file handle
       
   231 @param  aSessionHandle the associated client session handle
       
   232 */
       
   233 void CFbTopStreamIdCache::RCacheEntry::CreateFileStoreL(RFile& aFile, TInt aSessionHandle)
       
   234 	{
       
   235 	if (iFilestore == NULL)
       
   236 		{
       
   237 		iFilestore = CShiftedFileStore::FromL(aFile, iFileOffset);
       
   238 		iSessionHandle = aSessionHandle;
       
   239 		}
       
   240 	}
       
   241 
       
   242 /**
       
   243 It creates a file store if is not there i.e. if iFileStore is NULL.
       
   244 
       
   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
       
   248 */
       
   249 void CFbTopStreamIdCache::RCacheEntry::CreateFileStoreL(RFs& aFs, const TDesC& aFileName, TInt aSessionHandle)
       
   250 	{
       
   251 	if (iFilestore == NULL)
       
   252 		{
       
   253 		RFile file;
       
   254 		User::LeaveIfError(file.Open(aFs,aFileName,EFileShareReadersOnly));
       
   255 		iFilestore = CShiftedFileStore::FromL(file, iFileOffset);
       
   256 		iSessionHandle = aSessionHandle;
       
   257 		}
       
   258 	}