commsfwsupport/commselements/commsfw/src/cfutil.cpp
changeset 0 dfb7c4ff071f
child 15 51722b10598b
equal deleted inserted replaced
-1:000000000000 0:dfb7c4ff071f
       
     1 // Copyright (c) 2003-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 //
       
    15 
       
    16 #include <cfutil.h>
       
    17 #include <cfextras.h>
       
    18 #include <elements/cfmacro.h>
       
    19 #include <cflog.h>
       
    20 #include <cfforwardmsg.h>
       
    21 
       
    22 
       
    23 
       
    24 #ifdef _DEBUG
       
    25 // Panic category for "absolutely impossible!" vanilla ASSERT()-type panics from this module
       
    26 // (if it could happen through user error then you should give it an explicit, documented, category + code)
       
    27 _LIT(KSpecAssert_ElemCommsFwcftl, "ElemCommsFwcftl.");
       
    28 #endif
       
    29 
       
    30 using namespace CommsFW;
       
    31 
       
    32 EXPORT_C TInt CCFModuleChannelHandler::Send(const CommsFW::TCFMessage &aMessage)
       
    33 /** Send a message on the outgoing channel, blocks until the message has been sent.
       
    34 The rootserver is expected to run at high priority and retrieve pending messages
       
    35 quickly, also this exchange usually only happens at module startup and shutdown so
       
    36 it can usually be considered safe to block here.
       
    37 @param aMessage Message to send on the outgoing channel.
       
    38 @publishedPartner
       
    39 @released
       
    40 */
       
    41     {
       
    42 	TRequestStatus status;
       
    43 	iChannelPair.NotifySpaceAvailable(status);
       
    44 	User::WaitForRequest(status);
       
    45 	return iChannelPair.Send(aMessage);
       
    46     }
       
    47 
       
    48 EXPORT_C CCFModuleChannelHandler::~CCFModuleChannelHandler()
       
    49 /** D'tor. Dequeues this instance from the active scheduler.
       
    50 @publishedPartner
       
    51 @released
       
    52 */
       
    53     {
       
    54 	Cancel();
       
    55     }
       
    56 
       
    57 EXPORT_C CCFModuleChannelHandler::CCFModuleChannelHandler(TInt aPriority):CActive(aPriority)
       
    58 /** C'tor. Initialise the parent CActive.
       
    59 @publishedPartner
       
    60 @released
       
    61 */
       
    62     {
       
    63 	// Do nothing
       
    64     }
       
    65 
       
    66 EXPORT_C /*virtual*/ void CCFModuleChannelHandler::CFMessageDiscover(const CommsFW::TCFDiscoverMsg& aMessage)
       
    67 /** Default implementation of the TCFDiscoverMsg message. It will send a response indicating 
       
    68 there is no sub-modules in this module. Should be overridden if sub-modules are present in the module.
       
    69 @param aMessage The Discovery message which has been received from the Rootserver.
       
    70 @publishedPartner
       
    71 @released
       
    72 */
       
    73     {
       
    74 	// Default is no submodules, so we just return KErrNone
       
    75 	TCFDiscoverRespMsg resp(aMessage.Identifier(), KErrNone, EFalse);
       
    76 	TInt err = Send(resp);
       
    77 	if(KErrNone != err)
       
    78 		{
       
    79 		__CFLOG_1(KLogCommsFw, KLogWarning, _L8("CCFModuleChannelHandler::CFMessageDiscover(): Send returned %d"), err);
       
    80 		CFChannelError(err);
       
    81 		}
       
    82     }
       
    83 
       
    84 EXPORT_C /*virtual*/ void CCFModuleChannelHandler::CFMessageBind(const CommsFW::TCFBindMsg& aMessage)
       
    85 /** Default implementation of the TCFBindMsg message. It will send a response indicating 
       
    86 there is no submodules to bind to in this module. Should be overridden if sub-modules are present 
       
    87 in the module.
       
    88 @param aMessage The Bind message which has been received from the Rootserver.
       
    89 @publishedPartner
       
    90 @released
       
    91 */
       
    92     {
       
    93 	// Default is no submodules, so we just return KErrNotFound
       
    94 	TCFBindCompleteMsg resp(aMessage.Identifier(), KErrNotFound);
       
    95 	TInt err = Send(resp);
       
    96 	if(KErrNone != err)
       
    97 		{
       
    98 		__CFLOG_1(KLogCommsFw, KLogWarning, _L8("CCFModuleChannelHandler::CFMessageBind(): Send returned %d"), err);
       
    99 		CFChannelError(err);
       
   100 		}
       
   101     }
       
   102 
       
   103 EXPORT_C /*virtual*/ void CCFModuleChannelHandler::CFMessageUnbind(const CommsFW::TCFUnbindMsg& aMessage)
       
   104 /** Default implementation of the TCFUnbindMsg message. It will send a response indicating 
       
   105 there is no submodules to unbind from in this module. Should be overridden if sub-modules are present 
       
   106 in the module.
       
   107 @param aMessage The Unbind message which has been received from the Rootserver.
       
   108 @publishedPartner
       
   109 @released
       
   110 */
       
   111     {
       
   112 	// Default is no submodules, so we just return KErrNotFound
       
   113 	TCFUnbindCompleteMsg resp(aMessage.Identifier(), KErrNotFound);
       
   114 	TInt err = Send(resp);
       
   115 	if(KErrNone != err)
       
   116 		{
       
   117 		__CFLOG_1(KLogCommsFw, KLogWarning, _L8("CCFModuleChannelHandler::CFMessageUnbind(): Send returned %d"), err);
       
   118 		CFChannelError(err);
       
   119 		}
       
   120     }
       
   121 
       
   122 EXPORT_C /*virtual*/ void CCFModuleChannelHandler::CFMessageShutdown(const CommsFW::TCFShutdownMsg& aMessage)
       
   123 /** Default implementation of the TCFShutdownMsg message. it will do nothing. Should be overridden 
       
   124 if the module supports Shutdown.
       
   125 @param aMessage The Shutdown message which has been received from the Rootserver.
       
   126 @publishedPartner
       
   127 @released
       
   128 */
       
   129     {
       
   130 	(void) aMessage; // Avoid compiler warnings
       
   131     }
       
   132 
       
   133 EXPORT_C /*virtual*/ void CCFModuleChannelHandler::CFMessageForward(const CommsFW::TCFForwardMsg& aMessage)
       
   134 /** Default implementation of the CFMessageForward message. it will do nothing. Should be overridden 
       
   135 if the module supports Message Forwarding.
       
   136 @param aMessage The Forward message which has been received from the Rootserver.
       
   137 @publishedPartner
       
   138 @released
       
   139 */
       
   140     {
       
   141     aMessage.Msg().Complete( KErrNotSupported );
       
   142     }
       
   143 
       
   144 EXPORT_C /*virtual*/ void CCFModuleChannelHandler::CFMessageUnknown(const CommsFW::TCFMessage& aMessage)
       
   145 /** Default implementation for handling unknown messages. it will do nothing. Should be overridden 
       
   146 if the module wants to implement some handling for receiving unknown messages.
       
   147 @param aMessage The message which has been received from the Rootserver.
       
   148 @publishedPartner
       
   149 @released
       
   150 */
       
   151     {
       
   152 	(void) aMessage; // Avoid compiler warnings
       
   153     }
       
   154 
       
   155 EXPORT_C void CCFModuleChannelHandler::ConstructL(CommsFW::RCFChannel::TMsgQueues &aRxQueues, CommsFW::RCFChannel::TMsgQueues &aTxQueues)
       
   156 /** Second level constructor, must be called from derived implementations or the module 
       
   157 will PANIC when attempting to use the channels.
       
   158 @param aRxQueues Queues on which to listen for incoming messages.
       
   159 @param aTxQueues Queues on which to send outgoing messages.
       
   160 @publishedPartner
       
   161 @released
       
   162 */
       
   163     {
       
   164 	TInt ret;
       
   165 	if((ret = iChannelPair.CreateRecv(aRxQueues)) != KErrNone ||
       
   166 	   (ret = iChannelPair.CreateSend(aTxQueues)) != KErrNone)
       
   167 		{
       
   168 		User::Leave(ret);
       
   169 		}
       
   170 	CActiveScheduler::Add(this);
       
   171 	SetActive();
       
   172 	iChannelPair.NotifyDataAvailable(*this);
       
   173     }
       
   174 
       
   175 EXPORT_C /*virtual*/ void CCFModuleChannelHandler::DoCancel()
       
   176 /** Cancel function, will be called during destruction. Closes the channels contained.
       
   177 @internalComponent
       
   178 */
       
   179     {
       
   180  	iChannelPair.CancelDataAvailable();
       
   181  	iChannelPair.CloseNonGracefully();
       
   182     }
       
   183 
       
   184 EXPORT_C /*virtual*/ void CCFModuleChannelHandler::CFChannelError(TInt aError)
       
   185 /** Called when errors are encountered on using the channels. Does nothing but
       
   186 creating a log entry for [CommsFw,Warning]. Should be overridden if the module
       
   187 wants to supports handling of errors.
       
   188 @param aError The errorcode.
       
   189 @publishedPartner
       
   190 @released
       
   191 */
       
   192     {
       
   193 	// Do nothing is default, maybe instead we should panic?
       
   194 	(void) aError;
       
   195 	__CFLOG_1(KLogCommsFw, KLogWarning, _L8("ERROR CCFModuleChannelHandler::CFChannelError(%d)!"), aError);
       
   196     }
       
   197 
       
   198 EXPORT_C /*virtual*/ void CCFModuleChannelHandler::RunL()
       
   199 /** Receive a message and register for listening for more data on the incoming channel.
       
   200 wants to supports handling of errors.
       
   201 @internalComponent
       
   202 */
       
   203     {
       
   204 	if (iStatus != KErrNone)
       
   205 		{
       
   206 		__CFLOG_1(KLogCommsFw, KLogWarning, _L8("CCFModuleChannelHandler::RunL(): NotifyDataAvailable returned %d"), iStatus.Int());
       
   207 		CFChannelError(iStatus.Int());
       
   208 		return;
       
   209 		}
       
   210 	
       
   211 	// No error. Take the message from the channel.
       
   212 	TCFMessage msg;
       
   213 	TInt err(iChannelPair.Receive(msg));
       
   214 	if (KErrNone != err)
       
   215 		{
       
   216 		__CFLOG_1(KLogCommsFw, KLogWarning, _L8("CCFModuleChannelHandler::RunL(): Receive returned %d"), iStatus.Int());
       
   217 		CFChannelError(err);
       
   218 		return;
       
   219 		}
       
   220 
       
   221 	switch (msg.Code())
       
   222 		{
       
   223 		case TCFCommsMessage::ECodeDiscover:
       
   224 		CFMessageDiscover(reinterpret_cast<const TCFDiscoverMsg&>(msg));
       
   225 		break;
       
   226 		
       
   227 		case TCFCommsMessage::ECodeBind:
       
   228 		CFMessageBind(reinterpret_cast<const TCFBindMsg&>(msg));
       
   229 		break;
       
   230 		
       
   231 		case TCFCommsMessage::ECodeUnbind:
       
   232 		CFMessageUnbind(reinterpret_cast<const TCFUnbindMsg&>(msg));
       
   233 		break;
       
   234 		
       
   235 		case TCFCommsMessage::ECodeShutdown:
       
   236 		CFMessageShutdown(reinterpret_cast<const TCFShutdownMsg&>(msg));
       
   237 		break;
       
   238 
       
   239 		case TCFCommsMessage::ECodeForward:
       
   240 		CFMessageForward(reinterpret_cast<const TCFForwardMsg&>(msg));
       
   241 		break;
       
   242 
       
   243 		default:
       
   244 		CFMessageUnknown(msg);
       
   245 		break;
       
   246 		}
       
   247 
       
   248 	//Pend again
       
   249 	SetActive();
       
   250 	iChannelPair.NotifyDataAvailable(*this);
       
   251 	}
       
   252 
       
   253 
       
   254 EXPORT_C TBool CommsFW::GetVarFromIniData(const TDesC8& aIniData, const TDesC8& aSection, const TDesC8& aVarName, TPtrC8& aResult)
       
   255 /** Find a variable's value given a section name and a var name.
       
   256 @param aSection The section to search.
       
   257 @param aVarName The name to find.
       
   258 @param aResult The value.
       
   259 @return Success or fail.
       
   260 */
       
   261 	{
       
   262 	__ASSERT_DEBUG(aSection.Length() <= KMaxIniDataSectionNameLength, User::Panic(KSpecAssert_ElemCommsFwcftl, 1));
       
   263 	__ASSERT_DEBUG(aVarName.Length() <= KMaxIniDataSectionNameLength, User::Panic(KSpecAssert_ElemCommsFwcftl, 2));
       
   264 
       
   265 	TBuf8<KMaxIniDataSectionNameLength + 2> sectionToken;			// 2 extra chars for [sectionName]
       
   266 	TInt sectionStart = 0;
       
   267 	TInt sectionLen = 0;	// reassure compiler
       
   268 	TPtrC8 section;
       
   269 	// Sections are optional
       
   270 	if(aSection.Length() > 0)
       
   271 		{
       
   272 		_LIT8(KSectionTokenString,"[%S]");
       
   273 		sectionToken.Format(KSectionTokenString,&aSection);
       
   274 #ifdef SYMBIAN_NETWORKING_CFTRANSPORT
       
   275 		sectionStart = aIniData.FindF(sectionToken);
       
   276 #else
       
   277 		sectionStart = aIniData.Find(sectionToken);
       
   278 #endif
       
   279 		if (sectionStart == KErrNotFound)
       
   280 			return EFalse;
       
   281 		section.Set(aIniData.Mid(sectionStart));
       
   282 #ifdef SYMBIAN_NETWORKING_CFTRANSPORT
       
   283 		sectionStart += section.FindF(TPtrC8(_S8("]")));
       
   284 #else
       
   285 		sectionStart += section.Find(TPtrC8(_S8("]")));
       
   286 #endif
       
   287 		if (sectionStart == KErrNotFound)
       
   288 			return EFalse;
       
   289 		sectionStart++;
       
   290 		section.Set(aIniData.Mid(sectionStart));
       
   291 		
       
   292 #ifdef SYMBIAN_NETWORKING_CFTRANSPORT
       
   293 		sectionLen = section.FindF(TPtrC8(_S8("[")));
       
   294 #else
       
   295 		sectionLen = section.Find(TPtrC8(_S8("[")));
       
   296 #endif
       
   297 		if (sectionLen == KErrNotFound)
       
   298 			sectionLen = section.Length();
       
   299 		}
       
   300 	else
       
   301 		{
       
   302 		sectionLen = aIniData.Length();
       
   303 		}
       
   304 	TInt pos = 0;
       
   305 	FOREVER
       
   306 		{
       
   307 		section.Set(aIniData.Mid(sectionStart, sectionLen));
       
   308 #ifdef SYMBIAN_NETWORKING_CFTRANSPORT
       
   309 		pos = section.FindF(aVarName);
       
   310 #else
       
   311 		pos = section.Find(aVarName);
       
   312 #endif
       
   313 		if (pos==KErrNotFound)
       
   314 			return EFalse;
       
   315 		// Check that the token is at the start of the line, to avoid finding
       
   316 		// substrings or commented statements). If it isn't then continue
       
   317 		// searching from that point
       
   318 		TUint8 precedingChar;
       
   319 		if (pos == 0 ||
       
   320 			(precedingChar = section[pos - 1]) == '\n' ||
       
   321 			precedingChar == '\r')
       
   322 			{
       
   323 			break;
       
   324 			}
       
   325 		sectionStart += (pos + 1);
       
   326 		sectionLen -= (pos + 1);
       
   327 		}
       
   328 
       
   329 	section.Set(section.Mid(pos));
       
   330     // Found token - now find position of '='
       
   331 	pos = section.Locate('=');
       
   332 	if((KErrNotFound==pos) || ((pos+1)==section.Length()))
       
   333 		{
       
   334 		return EFalse;
       
   335 		}
       
   336 
       
   337 	// Shrink section to start after'='
       
   338 	TLex8 lex(section.Mid(++pos));
       
   339 	section.Set(section.Mid(pos));
       
   340 //	sectionStart+=pos;
       
   341 
       
   342 	// Set length of section to be to end of line or end of file
       
   343 	TInt length=section.Locate('\r');
       
   344 	if(length==KErrNotFound)
       
   345 		{
       
   346 		(void)lex.NextToken();
       
   347 		length=lex.MarkedToken().Length();
       
   348 		}
       
   349 	aResult.Set(section.Ptr(), length);
       
   350 	return(ETrue);
       
   351 	}
       
   352 
       
   353 //@TODO - why Configurator can't move to using same?
       
   354 EXPORT_C TBool CommsFW::GetVarFromIniData(const TDesC8& aIniData, const TDesC8 &aSection, const TDesC8 &aVarName, TInt &aResult)
       
   355 	{
       
   356 	TPtrC8 ptr;
       
   357 	if (CommsFW::GetVarFromIniData(aIniData, aSection, aVarName, ptr))
       
   358 		{
       
   359 		TUint32 result;
       
   360 		if (CommsFW::ConvertVal(ptr, result)==KErrNone)
       
   361 			{
       
   362 			aResult = result;
       
   363 			return(ETrue);
       
   364 			}
       
   365 		}
       
   366 	return(EFalse);
       
   367 	}
       
   368 
       
   369 //
       
   370 // COwnEntryList
       
   371 //
       
   372 
       
   373 EXPORT_C COwnEntryList::TOwnEntry::TOwnEntry(const TParse& aPath, const TEntry& aEntry)
       
   374 	{
       
   375 	TPtr fullName(iName.Des());
       
   376 	fullName.Copy(aPath.DriveAndPath());
       
   377 	fullName.Append(aEntry.iName);
       
   378 	}
       
   379 
       
   380 EXPORT_C COwnEntryList::COwnEntryList(TInt aGranularity)
       
   381 : iArray(aGranularity)
       
   382 	{
       
   383 	}
       
   384 
       
   385 EXPORT_C COwnEntryList::~COwnEntryList()
       
   386 	{
       
   387 	iArray.Close();
       
   388 	}
       
   389 
       
   390 /*
       
   391 EXPORT_C COwnEntryList* COwnEntryList::NewL(TInt aGranularity)
       
   392 	{
       
   393 	COwnEntryList* self = new(ELeave) COwnEntryList(aGranularity);
       
   394 	CleanupStack::PushL(self);
       
   395 	if(aDir)
       
   396 		{
       
   397 		self->AddL(*aDir);
       
   398 		}
       
   399 	CleanupStack::Pop(self);
       
   400 	return self;
       
   401 	}
       
   402 */
       
   403 
       
   404 EXPORT_C TInt COwnEntryList::Count() const
       
   405 	{
       
   406 	return iArray.Count();
       
   407 	}
       
   408 
       
   409 EXPORT_C const COwnEntryList::TOwnEntry& COwnEntryList::operator[](TInt anIndex) const
       
   410 	{
       
   411 	return iArray[anIndex];
       
   412 	}
       
   413 
       
   414 EXPORT_C void COwnEntryList::AddL(const TOwnEntry& aEntry)
       
   415 	{
       
   416 	User::LeaveIfError(iArray.Append(aEntry));
       
   417 	}
       
   418 
       
   419 EXPORT_C void COwnEntryList::AddL(const COwnEntryList& aDir)
       
   420 	{
       
   421 	const TInt cnt = aDir.Count();
       
   422 	for(TInt i = 0; i < cnt; ++i)
       
   423 		{
       
   424 		AddL(aDir[i]);
       
   425 		}
       
   426 	}
       
   427 
       
   428 EXPORT_C void COwnEntryList::WildScanAcrossDrivesL(const TDesC& aDir, const TDesC& aFileMask)
       
   429 	{
       
   430 	iArray.Reset();
       
   431 	TAutoClose<RFs> fs;
       
   432 	User::LeaveIfError(fs.iObj.Connect());
       
   433 	fs.PushL();
       
   434 	TFindFile ff(fs.iObj);
       
   435 	TParse fullEntry;
       
   436 	CDir* dir;
       
   437 	if(ff.FindWildByDir(aFileMask, aDir, dir) == KErrNone)
       
   438 		{
       
   439 		do 
       
   440 			{
       
   441 			const TInt cnt = dir->Count();
       
   442 			for(TInt i = 0; i < cnt; ++i)
       
   443 				{
       
   444 				const TEntry& entry = (*dir)[i];
       
   445 				fullEntry.Set(entry.iName, &ff.File(), NULL);      
       
   446 				AddL(TOwnEntry(fullEntry, entry));
       
   447 				}
       
   448 			delete dir;
       
   449 			}
       
   450 		while(ff.FindWild(dir) == KErrNone);
       
   451 		}	
       
   452 	fs.Pop();
       
   453 	}
       
   454 
       
   455 EXPORT_C void COwnEntryList::UniqueWildScanAcrossDrivesL(const TDesC& aDir, const TDesC& aFileMask)
       
   456 /**
       
   457  * Function is used to scan unique files from drives starting from Y: to A: then last Z:. The scanning 
       
   458  * is done by module name.Files with unique name module name will be scanned.This function is used by Rootserver to 
       
   459  * scan cmi files unique by name.It can be used by other internal components for the similar use.
       
   460  * 
       
   461  * @internalComponent
       
   462  */
       
   463 	{
       
   464 	iArray.Reset();
       
   465 	TAutoClose<RFs> fs;
       
   466 	User::LeaveIfError(fs.iObj.Connect());
       
   467 	fs.PushL();
       
   468 	TFindFile ff(fs.iObj);
       
   469 	TParse fullEntry;
       
   470 	CDir* dir;
       
   471 	RArray<TEntry> files;
       
   472 	TBool found;
       
   473 	if(ff.FindWildByDir(aFileMask, aDir, dir) == KErrNone)
       
   474 		{
       
   475 		do 
       
   476 			{
       
   477 			const TInt cnt = dir->Count();
       
   478 			for(TInt i = 0; i < cnt; ++i)
       
   479 				{
       
   480 				const TEntry& entry = (*dir)[i];
       
   481 		               if(files.Count()!=0)
       
   482 				      {
       
   483 					found = EFalse;
       
   484 					for( TInt Index=0;Index<files.Count();Index++)
       
   485 			    	           {
       
   486 						if(files[Index].iName.CompareF(entry.iName)==0)
       
   487 						     {
       
   488 							found = ETrue;
       
   489 					             }
       
   490 				             }
       
   491 	                            if(!found)
       
   492 	    	                         {
       
   493 				    	   files.Append(entry);
       
   494 					   fullEntry.Set(entry.iName, &ff.File(), NULL);      
       
   495 					   AddL(TOwnEntry(fullEntry, entry));
       
   496 				    	     }
       
   497 				       }
       
   498 		        	else
       
   499 			          {
       
   500 			           files.Append(entry);
       
   501 				    fullEntry.Set(entry.iName, &ff.File(), NULL);      
       
   502 				    AddL(TOwnEntry(fullEntry, entry));
       
   503 				    }		
       
   504 							
       
   505 		         }
       
   506 		     delete dir;
       
   507 			
       
   508 	           }
       
   509 	           while(ff.FindWild(dir) == KErrNone);
       
   510         	}	
       
   511 	files.Close();	
       
   512 	fs.Pop();
       
   513 	}
       
   514 
       
   515 //
       
   516 // class RCFHeap
       
   517 //
       
   518 
       
   519 #if defined(__CFLOG_ACTIVE) || defined(SYMBIAN_TRACE_ENABLE)
       
   520 
       
   521 void RCFSharedHeap::WalkFunc(TAny* aContext, TCellType aType, TAny* aBase, TInt /*aSize*/)
       
   522 	{
       
   523 	(void)aBase;
       
   524 	if(aType == EGoodAllocatedCell)
       
   525 		{
       
   526 		TLogInfo* logInfo = reinterpret_cast<TLogInfo*>(aContext);
       
   527 		__CFLOG_VAR((logInfo->iSubSystem, logInfo->iComponent, _L8("  0x%x"), (TUint) aBase + (TUint) RHeap::EAllocCellSize));
       
   528 		
       
   529 #ifdef SYMBIAN_TRACE_ENABLE
       
   530 	TLogTextBuf buf;
       
   531 	TBool loggingSuccess = EFalse;
       
   532 	if(logInfo->iSubSystem.Length() < KMaxLogTextLength)
       
   533 		{
       
   534 		buf.Append(logInfo->iSubSystem);
       
   535 		_LIT8(KSpace, " ");
       
   536 		if(buf.Length() + KSpace().Length() < KMaxLogTextLength)
       
   537 			{			
       
   538 			buf.Append(KSpace);			
       
   539 			if(buf.Length() + logInfo->iComponent.Length() < KMaxLogTextLength)
       
   540 				{
       
   541 				buf.Append(logInfo->iComponent);
       
   542 				if(buf.Length() + KSpace().Length() < KMaxLogTextLength)
       
   543 					{			
       
   544 					buf.Append(KSpace);	
       
   545 					_LIT8(KHexNumberFormat, " 0x%x");
       
   546 					buf.AppendFormatIgnoreOverflow(KHexNumberFormat, (TUint) aBase + (TUint) RHeap::EAllocCellSize);
       
   547 					loggingSuccess = UTracePfAny(KPrimaryFilter, KText, ETrue, EFalse, 0, buf.Ptr(), buf.Length());	
       
   548 					}
       
   549 				}	
       
   550 			}	
       
   551 		}
       
   552 		if(loggingSuccess == EFalse) //May happen if buffer length exceeds KMaxLogTextLength due to longer names of logInfo->iSubSystem and/or logInfo->iComponent 
       
   553 									 //Atleast the below log helps to identify that there is a leak
       
   554 			{
       
   555 			_LIT8(KCantLogNames, "??? ??? 0x%x"); //Atleast this should fit
       
   556 			buf.Zero();
       
   557 			buf.AppendFormatIgnoreOverflow(KCantLogNames, (TUint) aBase + (TUint) RHeap::EAllocCellSize);
       
   558 			loggingSuccess = UTracePfAny(KPrimaryFilter, KText, ETrue, EFalse, 0, buf.Ptr(), buf.Length());		
       
   559 			}
       
   560 #endif //SYMBIAN_TRACE_ENABLE			
       
   561 		}
       
   562 	}
       
   563 
       
   564 #endif //defined(__CFLOG_ACTIVE) || defined(SYMBIAN_TRACE_ENABLE)
       
   565 
       
   566 EXPORT_C TInt RCFSharedHeap::AccessCount() const 
       
   567 	{
       
   568 	return iAccessCount;
       
   569 	}
       
   570 
       
   571 EXPORT_C void RCFSharedHeap::LogAllocatedCells(const TDesC8& aSubSystem, const TDesC8& aComponent)
       
   572 	{
       
   573 #if defined(__CFLOG_ACTIVE) || defined(SYMBIAN_TRACE_ENABLE)
       
   574 	TLogInfo logInfo(aSubSystem, aComponent);
       
   575 	DebugFunction(EWalk, (TAny*)WalkFunc, &logInfo);
       
   576 #else
       
   577 	(void) aSubSystem;
       
   578 	(void) aComponent;
       
   579 #endif
       
   580 	}
       
   581 
       
   582 
       
   583 //
       
   584 // Other utils
       
   585 //
       
   586 
       
   587 namespace CommsFW
       
   588 {
       
   589 
       
   590 EXPORT_C TInt ConvertVal(const TDesC8& aVar, TUint32& aResult)
       
   591 	{
       
   592 	TPtrC8 ptr(aVar);
       
   593 	TRadix radix;
       
   594 	_LIT8(KHexPrefix, "0x");
       
   595 	if(ptr.Left(2).CompareF(KHexPrefix) == 0)
       
   596 		{
       
   597 		ptr.Set(ptr.Mid(2));
       
   598 		radix = EHex;
       
   599 		}
       
   600 	else
       
   601 		{
       
   602 		radix = EDecimal;
       
   603 		}
       
   604 	TLex8 lex(ptr);
       
   605 	TUint32 result;
       
   606 	TInt err = lex.Val(result, radix);
       
   607 	if (err==KErrNone)
       
   608 		{
       
   609 		aResult = result;
       
   610 		}
       
   611 	return err;
       
   612 	}
       
   613 
       
   614 EXPORT_C TInt ConvertVal(const TDesC8& aVar, TUint16& aResult)
       
   615 	{
       
   616 	TUint32 result = 0xFFFFFFFF;
       
   617 	TInt err = ConvertVal(aVar, result);
       
   618 	if (err==KErrNone && result<=0xFFFF)
       
   619 		{
       
   620 		aResult = result;
       
   621 		}
       
   622 	return err;
       
   623 	}
       
   624 
       
   625 }
       
   626 
       
   627