loggingservices/eventlogger/LogServ/src/LogServResourceInterpreter.cpp
changeset 51 7d4490026038
parent 31 ba1c4f4a893f
equal deleted inserted replaced
40:b8bdbc8f59c7 51:7d4490026038
     1 // Copyright (c) 2002-2009 Nokia Corporation and/or its subsidiary(-ies).
     1 // Copyright (c) 2002-2010 Nokia Corporation and/or its subsidiary(-ies).
     2 // All rights reserved.
     2 // All rights reserved.
     3 // This component and the accompanying materials are made available
     3 // This component and the accompanying materials are made available
     4 // under the terms of "Eclipse Public License v1.0"
     4 // under the terms of "Eclipse Public License v1.0"
     5 // which accompanies this distribution, and is available
     5 // which accompanies this distribution, and is available
     6 // at the URL "http://www.eclipse.org/legal/epl-v10.html".
     6 // at the URL "http://www.eclipse.org/legal/epl-v10.html".
    16 
    16 
    17 #include <bautils.h>
    17 #include <bautils.h>
    18 #include "logservpanic.h"
    18 #include "logservpanic.h"
    19 #include "LogServResourceInterpreter.h"
    19 #include "LogServResourceInterpreter.h"
    20 
    20 
    21 // Constants
    21 //LogWrap resoure file name
    22 const TInt KLogResourceFileGranularity = 2;
    22 _LIT(KResourceFileWrapper, "\\resource\\logeng\\logwrap.rsc");
    23 
    23 
    24 // Literal constants
    24 const TInt KStringsArrayGranularity = 20;
    25 _LIT(KResourceFileClient,"\\private\\101f401d\\logserv.rsc");
       
    26 _LIT(KResourceFileWrapper,"\\resource\\logeng\\logwrap.rsc");
       
    27 
    25 
       
    26 /**
       
    27 Creates a CLogServResourceInterpreter instance.
       
    28 The created CLogServResourceInterpreter instance will load into memory the content of the LogWrap
       
    29 resource file.
       
    30   
       
    31 @param aFs Reference to a file session object, used later for reading the content of the resource file.
    28 
    32 
    29 /////////////////////////////////////////////////////////////////////////////////////////
    33 @leave  KErrNoMemory, an out of memory condition has occurred;
    30 // -----> CLogServResourceInterpreter (source)
    34                       Note that the function may leave with database specific errors and
    31 /////////////////////////////////////////////////////////////////////////////////////////
    35                       other system-wide error codes.
    32 CLogServResourceInterpreter::CLogServResourceInterpreter(RFs& aFsSession) :	
    36 */
    33 	iFsSession(aFsSession), iResourceFiles(KLogResourceFileGranularity),
    37 CLogServResourceInterpreter* CLogServResourceInterpreter::NewL(RFs& aFs)
    34 	iResourceStringCache(CResourceStringCacheEntry::Offset()),
       
    35 	iResourceStringCacheIter(iResourceStringCache) 
       
    36 	{
    38 	{
    37 	}
    39 	CLogServResourceInterpreter* self = new (ELeave) CLogServResourceInterpreter(aFs);
    38 
       
    39 CLogServResourceInterpreter::~CLogServResourceInterpreter()
       
    40 	{
       
    41 	const TInt count = iResourceFiles.Count();
       
    42 	for(TInt i=0; i<count; i++)
       
    43 		{
       
    44 		TResourceFileEntry& entry = iResourceFiles[i];
       
    45 		entry.iFile.Close();
       
    46 		}
       
    47 	iResourceFiles.Close();
       
    48 
       
    49 	// Iterate through list of cache entries deleting them in turn.	
       
    50 	CResourceStringCacheEntry* item ;
       
    51 	iResourceStringCacheIter.SetToFirst() ;
       
    52 	while ((item = iResourceStringCacheIter++) != NULL)
       
    53       {
       
    54         iResourceStringCache.Remove(*item);
       
    55         delete item;
       
    56         }
       
    57     }
       
    58 
       
    59 void CLogServResourceInterpreter::ConstructL()
       
    60 	{
       
    61 	// Load standard resource files
       
    62 	LoadResourceFileL(KResourceFileClient, ELogServer);
       
    63 	LoadResourceFileL(KResourceFileWrapper, ELogWrap);
       
    64 	}
       
    65 
       
    66 CLogServResourceInterpreter* CLogServResourceInterpreter::NewL(RFs& aFsSession)
       
    67 	{
       
    68 	CLogServResourceInterpreter* self = new(ELeave) CLogServResourceInterpreter(aFsSession);
       
    69 	CleanupStack::PushL(self);
    40 	CleanupStack::PushL(self);
    70 	self->ConstructL();
    41 	self->ConstructL();
    71 	CleanupStack::Pop(self);
    42 	CleanupStack::Pop(self);
    72 	return self;
    43 	return self;
    73 	}
    44 	}
    74 
    45 
    75 /////////////////////////////////////////////////////////////////////////////////////////
    46 /**
    76 /////////////////////////////////////////////////////////////////////////////////////////
    47 Destroys CLogServResourceInterpreter object deallocating all previously allocated resources
    77 /////////////////////////////////////////////////////////////////////////////////////////
    48 (the resource file, the memory for the loaded resource strings) 
       
    49 */
       
    50 CLogServResourceInterpreter::~CLogServResourceInterpreter()
       
    51 	{
       
    52 	iFile.Close();
       
    53 	for(TInt i=iStrings.Count()-1;i>=0;--i)
       
    54 		{
       
    55 		delete iStrings[i].iString;
       
    56 		}
       
    57 	iStrings.Close();
       
    58     }
    78 
    59 
    79 void CLogServResourceInterpreter::CreateResourceReaderLC(TResourceReader& aReader, TInt aId, TResourceType aType)
    60 /**
       
    61 Creates a resource reader object for the resource identified by the aId parameter.
       
    62 
       
    63 @param aReader Output parameter. The resource reader object, created by this call.
       
    64 @param aId Resource item identifier.
       
    65 
       
    66 @leave  KErrNoMemory, an out of memory condition has occurred;
       
    67                       Note that the function may leave with database specific errors and
       
    68                       other system-wide error codes. 
       
    69 */
       
    70 void CLogServResourceInterpreter::CreateResourceReaderLC(TResourceReader& aReader, TInt aId)
    80 	{
    71 	{
    81 	HBufC8* buf = GetResourceBufferL(aId, aType) ;		
    72 	HBufC8* string = GetStringL(aId);		
    82 
    73 	//Resource reader needs to be created with a copy of the string resource as otherwise
    83 	// Resource reader needs to be created with a copy of the cache buffer as otherwise
    74 	//our "HBufC8*" string will be deleted when the resource reader is deleted!
    84 	// our cache buffer will be deleted when the resource reader is deleted!
    75 	aReader.SetBuffer(string->AllocLC());
    85 	aReader.SetBuffer(buf->AllocLC());
       
    86 	}
       
    87 	
       
    88 HBufC8* CLogServResourceInterpreter::GetResourceBufferL(TInt aId, TResourceType aType)
       
    89 	{
       
    90 
       
    91 	// Attempt to find the requested resource in the cache
       
    92 	CResourceStringCacheEntry* cacheEntry = FindCachedResourceString(aId, aType) ;	
       
    93 
       
    94 	HBufC8* buf ;
       
    95 	if (!cacheEntry)
       
    96 		{
       
    97 		// Not found in cache, load from resource file and add to the
       
    98 		// linked list which forms the cache. 
       
    99 		buf = ResourceFileForType(aType).AllocReadLC(aId);
       
   100 		cacheEntry = CResourceStringCacheEntry::NewL(aId, aType, buf) ;
       
   101 		iResourceStringCache.AddLast(*cacheEntry) ;
       
   102 		
       
   103 		// buf is now the responsibility of iResourceStringCache and
       
   104 		// will be tidied up by the destructor...
       
   105 		CleanupStack::Pop(buf);
       
   106 		}
       
   107 	else
       
   108 		{
       
   109 		buf = cacheEntry->ResourceString();
       
   110 		}
       
   111 	return buf ;
       
   112 	}
    76 	}
   113 
    77 
   114 /////////////////////////////////////////////////////////////////////////////////////////
    78 /**
   115 /////////////////////////////////////////////////////////////////////////////////////////
    79 Initializes CLogServResourceInterpreter data members with their default values.
   116 /////////////////////////////////////////////////////////////////////////////////////////
    80 @param aFs Reference to a file session object, used later for reading the content of the resource file.  
       
    81 */
       
    82 CLogServResourceInterpreter::CLogServResourceInterpreter(RFs& aFs) :	
       
    83 	iFs(aFs), 
       
    84 	iStrings(KStringsArrayGranularity)
       
    85 	{
       
    86 	}
   117 
    87 
   118 void CLogServResourceInterpreter::LoadResourceFileL(const TDesC& aName, TResourceType aType)
    88 /**
       
    89 Loads the content of the LogWrap resource file.
       
    90 */
       
    91 void CLogServResourceInterpreter::ConstructL()
   119 	{
    92 	{
   120 	LOGTEXT3("CLogServResourceInterpreter::LoadResourceFileL(%S, %d)", &aName, aType);
       
   121 
       
   122 	// Find the resource file
    93 	// Find the resource file
   123     TFileName fileName;
    94   TFileName fileName;
   124 	fileName.Copy(RProcess().FileName());
    95 	fileName.Copy(RProcess().FileName());
   125 
    96 
   126     TParse parse;
    97   TParse parse;
   127     parse.Set(aName, &fileName, NULL);
    98   parse.Set(KResourceFileWrapper, &fileName, NULL);
   128 	fileName = parse.FullName();
    99 	fileName = parse.FullName();
   129 
   100 
   130 	// Get language of resource file
   101 	// Get language of resource file
   131 	BaflUtils::NearestLanguageFile(iFsSession, fileName);
   102 	BaflUtils::NearestLanguageFile(iFs, fileName);
   132 
   103 
   133 	// Check the entry exists on this drive (e.g. if we are running the log server
   104 	// Check the entry exists on this drive (e.g. if we are running the log server
   134 	// from RAM, then default to the ROM if no RSC on the current drive exists).
   105 	// from RAM, then default to the ROM if no RSC on the current drive exists).
   135 	TEntry fsEntry;
   106 	TEntry fsEntry;
   136 	TInt err = iFsSession.Entry(fileName, fsEntry);
   107 	TInt err = iFs.Entry(fileName, fsEntry);
   137 	if ( err == KErrNotFound || err == KErrPathNotFound )
   108 	if(err == KErrNotFound || err == KErrPathNotFound)
   138 		{
   109 		{
   139 		// Switch to ROM (we might already have been launching from the ROM,
   110 		// Switch to ROM (we might already have been launching from the ROM,
   140 		// in which case this will have no effect anyway).
   111 		// in which case this will have no effect anyway).
   141 		fileName[0] = 'Z';
   112 		fileName[0] = 'Z';
   142 		}
   113 		}
   143 
   114 	iFile.OpenL(iFs, fileName);
   144 	// Open resource file
       
   145 	TResourceFileEntry entry;
       
   146 	entry.iType = aType;
       
   147 	CleanupClosePushL(entry.iFile);
       
   148 
       
   149 	LOGTEXT2("CLogServResourceInterpreter::LoadResourceFileL() - localized name is: %S", &fileName);
       
   150 	
       
   151 	entry.iFile.OpenL(iFsSession, fileName);
       
   152 	
       
   153 	LOGTEXT("CLogServResourceInterpreter::LoadResourceFileL() - resource file open");
       
   154 
       
   155 	// I'm leaving this in just in case somebody decides to try and add this code
       
   156 	// without realising the consequences...
       
   157 #ifdef __CAN_BREAK_BC__
       
   158 	//
       
   159 	// Can't use BAFL 'NAME' support in resource file, since this
       
   160 	// will break data compatibility with old software using the existing
       
   161 	// logwrap and logcli RSG header files :((
       
   162 	entry.iFile.ConfirmSignatureL();
       
   163 	__ASSERT_ALWAYS(entry.iFile.Offset() != 0, Panic(ELogNoResourceName));
       
   164 #endif
       
   165 
       
   166 	User::LeaveIfError(iResourceFiles.Append(entry));
       
   167 	CleanupStack::Pop(&entry.iFile);
       
   168 
       
   169 	LOGTEXT("CLogServResourceInterpreter::LoadResourceFileL() - end");
       
   170 	}
   115 	}
   171 
   116 
   172 const RResourceFile& CLogServResourceInterpreter::ResourceFileForType(TResourceType aType) const
   117 /**
       
   118 Attempts to read the resource string, identified by the aId parameter, from 
       
   119 the iStrings array. If the resource stringis not there, it will be loaded from the
       
   120 resource file and put in iStrings array.
       
   121 @param aId Resource string identifier.
       
   122 @return HBufC8 object containing the requested string 
       
   123 @leave  KErrNoMemory, an out of memory condition has occurred;
       
   124                       Note that the function may leave with database specific errors and
       
   125                       other system-wide error codes. 
       
   126 */
       
   127 HBufC8* CLogServResourceInterpreter::GetStringL(TInt aId)
   173 	{
   128 	{
   174 	const RResourceFile* ret = NULL;
   129 	TLinearOrder<TResourceString> order(&CLogServResourceInterpreter::Compare);
   175 	//
   130 	//Try to find the requested resource in the cached strings
   176 	const TInt count = iResourceFiles.Count();
   131 	TInt idx = iStrings.FindInOrder(TResourceString(aId, NULL), order);
   177 	for(TInt i=0; i<count; i++)
   132 	if(idx == KErrNotFound)
   178 		{
   133 		{
   179 		const TResourceFileEntry& entry = iResourceFiles[i];
   134 		//String not in the cache, load it from the resource file
   180 		if	(entry.iType == aType)
   135 		iStrings.ReserveL(iStrings.Count() + 1);
   181 			{
   136 		HBufC8* buf = iFile.AllocReadL(aId);
   182 			ret = &entry.iFile;
   137 		TResourceString entry(aId, buf);
   183 			break;
   138 		#ifdef _DEBUG
   184 			}
   139 		TInt err = 
       
   140 		#endif	
       
   141 		iStrings.InsertInOrder(entry, order);
       
   142 		__ASSERT_DEBUG(err == KErrNone, User::Invariant());
       
   143 		return buf;
   185 		}
   144 		}
   186 	__ASSERT_ALWAYS(ret != NULL, Panic(ELogNoResourceForId));
   145 	return iStrings[idx].iString;
   187 	return *ret;
       
   188 	}
   146 	}
   189 
   147 
       
   148 /**
       
   149 Compares two iStrings entries.
       
   150 Used for sorting/finding entries in iStrings sorted array.
   190 
   151 
   191 CLogServResourceInterpreter::CResourceStringCacheEntry * CLogServResourceInterpreter::FindCachedResourceString(const TInt aId, TResourceType aType)
   152 @param  aLeft  Left entry to be compared
       
   153 @param  aRight Right entry to be compared
       
   154 @return -1 aLeft is less than aRight, 0 entries are equal, 1 aLeft is bigger than aRight 
       
   155 */
       
   156 TInt CLogServResourceInterpreter::Compare(const CLogServResourceInterpreter::TResourceString& aLeft, 
       
   157  										  const CLogServResourceInterpreter::TResourceString& aRight)
   192 	{
   158 	{
   193 	CLogServResourceInterpreter::CResourceStringCacheEntry* item ;
   159 	TInt64 res = (TInt64)aLeft.iId - (TInt64)aRight.iId;
   194 	
   160 	return res > 0LL ? 1 : (res < 0LL ? -1 : 0);
   195 	// Iterate through linked list of cache entries looking for a 
       
   196 	// match - if no match found will drop out with a NULL pointer.
       
   197 	iResourceStringCacheIter.SetToFirst() ;
       
   198 	while ((item = iResourceStringCacheIter++) != NULL)
       
   199 		{
       
   200 		if ((item->ResourceType() == aType) && (item->ResourceId() == aId))
       
   201 			{
       
   202 			break ;
       
   203 			}
       
   204 		};
       
   205 	return item ;
       
   206 	}
   161 	}
   207 	
       
   208 
       
   209 /////////////////////////////////////////////////////////////////////////////////////////
       
   210 // -----> CLogServResourceInterpreter::CResourceStringCacheEntry (source)
       
   211 /////////////////////////////////////////////////////////////////////////////////////////	
       
   212 CLogServResourceInterpreter::CResourceStringCacheEntry::CResourceStringCacheEntry(TInt aResourceId, CLogServResourceInterpreter::TResourceType aType, HBufC8* aResourceString) : iResourceId (aResourceId), iResourceType (aType), iResourceString(aResourceString)
       
   213 	{
       
   214 	}
       
   215 
       
   216 
       
   217 CLogServResourceInterpreter::CResourceStringCacheEntry::~CResourceStringCacheEntry()
       
   218 	{
       
   219 	delete iResourceString ;
       
   220 	}
       
   221 
       
   222 
       
   223 CLogServResourceInterpreter::CResourceStringCacheEntry* CLogServResourceInterpreter::CResourceStringCacheEntry::NewL(TInt aResourceId, CLogServResourceInterpreter::TResourceType aType, HBufC8* aResourceString)
       
   224 	{
       
   225 	return new(ELeave) CResourceStringCacheEntry(aResourceId, aType, aResourceString);
       
   226 	}
       
   227 	
       
   228 TUint CLogServResourceInterpreter::CResourceStringCacheEntry::ResourceId(void)
       
   229 	{
       
   230 	return iResourceId ;
       
   231 	}
       
   232 	
       
   233 CLogServResourceInterpreter::TResourceType CLogServResourceInterpreter::CResourceStringCacheEntry::ResourceType(void)
       
   234 	{
       
   235 	return iResourceType ;
       
   236 	}
       
   237 
       
   238 HBufC8* CLogServResourceInterpreter::CResourceStringCacheEntry::ResourceString (void)
       
   239 	{
       
   240 	return iResourceString ;
       
   241 	}
       
   242 	
       
   243 TInt CLogServResourceInterpreter::CResourceStringCacheEntry::Offset() 
       
   244 	{
       
   245     return (_FOFF(CLogServResourceInterpreter::CResourceStringCacheEntry, iLink));	
       
   246 	}
       
   247