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