commsfwsupport/commselements/commsfw/src/cflog.cpp
changeset 0 dfb7c4ff071f
child 67 00c6709d25aa
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 /**
       
    17  @file
       
    18  @internalTechnology
       
    19 */
       
    20 
       
    21 // From CFLOG's perspective it's always included; other components choose this by whether
       
    22 // they #include "cflog.mmh" AND Flogger is active
       
    23 #define __CFLOG_INCLUDED
       
    24 
       
    25 #include "cflog.h"
       
    26 #include <cfshared.h>
       
    27 #include <e32debug.h>
       
    28 
       
    29 
       
    30 #if defined(__CFLOG_ACTIVE)
       
    31 
       
    32 #if defined(__WINS__)
       
    33 #include <emulator.h>
       
    34 #endif
       
    35 
       
    36 const TInt KDefaultConnectionArrayLength = 64;
       
    37 
       
    38 class TCFLogTags
       
    39 	{
       
    40 public:
       
    41 	TCFLogTags(const TBufC8<KMaxTagLength>& aComponent,
       
    42 			   const TBufC8<KMaxTagLength>& aSubSystem);
       
    43 	const TBufC8<KMaxTagLength>& Component() const;
       
    44 	const TBufC8<KMaxTagLength>& SubSystem() const;
       
    45 
       
    46 	// for find method
       
    47 	static TBool Matches(const TCFLogTags& aTags1, const TCFLogTags& aTags2);
       
    48 
       
    49 private:
       
    50 	TBufC8<KMaxTagLength> iComponent;
       
    51 	TBufC8<KMaxTagLength> iSubSystem;
       
    52 	};
       
    53 
       
    54 
       
    55 NONSHARABLE_CLASS(CCFLog) : public CBase
       
    56 /** Interface class implementing CFlogger and used by the CFlogger 
       
    57 interface class @see CCFlogIf
       
    58 @internalTechnology */
       
    59 	{
       
    60 private:
       
    61 	CCFLog();
       
    62 	void ConstructL();
       
    63 public:
       
    64 	~CCFLog();
       
    65  	static CCFLog *NewL();
       
    66 	
       
    67 	TInt DoConnect();
       
    68 	TInt DoClose();
       
    69 
       
    70 	// 
       
    71 	void DoWrite(const TDesC8& aSubsystem, const TDesC8& aComponent, const TDesC16& aText);
       
    72 	void DoWriteFormat(const TDesC8& aSubsystem, const TDesC8& aComponent, TRefByValue<const TDesC16> aFmt, ...);
       
    73 	void DoWriteFormat(const TDesC8& aSubsystem, const TDesC8& aComponent, TRefByValue<const TDesC16> aFmt, VA_LIST& aList);
       
    74 	void DoWrite(const TDesC8& aSubsystem, const TDesC8& aComponent, const TDesC8& aText);
       
    75 	void DoWriteFormat(const TDesC8& aSubsystem, const TDesC8& aComponent, TRefByValue<const TDesC8> aFmt, ...);
       
    76 	void DoWriteFormat(const TDesC8& aSubsystem, const TDesC8& aComponent, TRefByValue<const TDesC8> aFmt, VA_LIST& aList);
       
    77 	void DoHexDump(const TDesC8& aSubsystem, const TDesC8& aComponent, const TText* aHeader, const TText* aMargin, const TUint8* aPtr, TInt aLen);
       
    78 	void DoWriteBinary(const TDesC8& aSubsystem, const TDesC8& aComponent, const TDesC8& aData);
       
    79 
       
    80 	typedef RFastLock RCFLockType;
       
    81 	RCFLockType& CsLock();
       
    82 	TInt UserCount();
       
    83 
       
    84 private:
       
    85 	TInt GetFloggerPtr(const TDesC8& aSubsystem, const TDesC8& aComponent, RFileLogger*& aFlogger);
       
    86 
       
    87 private:
       
    88 	typedef RAllocator RCFAllocator;
       
    89 	RCFAllocator* iProcessHeap;
       
    90 	RCFLockType iCsLock;
       
    91 	TInt iUserCount;
       
    92 	RArray<TCFLogTags> iTags;
       
    93 	RArray<RFileLogger> iFloggers;
       
    94 
       
    95 #if defined(__WINS__)
       
    96 	class TCFWin32Threads
       
    97 		{
       
    98 	public:
       
    99 		TCFWin32Threads() : iThreads(KDefaultConnectionArrayLength, 0)
       
   100 			{ }
       
   101 		~TCFWin32Threads()
       
   102 			{
       
   103 			iThreads.Close();
       
   104 			}
       
   105 			TBool CheckWin32Thread(TUint32& aWin32Thread, RCFAllocator* aProcessHeap);
       
   106 	private:
       
   107 		RArray<TUint32> iThreads;
       
   108 		};
       
   109 
       
   110 	TCFWin32Threads iWin32Threads;
       
   111 
       
   112 #endif
       
   113 	};
       
   114 	
       
   115 #if defined(__WINS__)
       
   116 TBool CCFLog::TCFWin32Threads::CheckWin32Thread(TUint32& aWin32Thread, RCFAllocator* aProcessHeap)
       
   117 	{
       
   118 	TBool result = EFalse;
       
   119 	RCFAllocator* threadHeap = NULL;
       
   120 	
       
   121 	Emulator::Lock();
       
   122 	aWin32Thread = ::GetCurrentThreadId();
       
   123 	Emulator::Unlock();
       
   124 	if(iThreads.Find(aWin32Thread) == KErrNotFound)
       
   125 		{
       
   126 		threadHeap = User::SwitchHeap(aProcessHeap);
       
   127 		if(iThreads.Append(aWin32Thread) == KErrNone)
       
   128 			{
       
   129 			result = ETrue;
       
   130 			}
       
   131 		User::SwitchHeap(threadHeap);
       
   132 		}
       
   133 	return result;
       
   134 	}
       
   135 
       
   136 #endif
       
   137 
       
   138 EXPORT_C CCFLogIf* CCFLogIf::NewL()
       
   139 /** Creates new CCFLogIf object
       
   140 @return CCFLog* pointer to the new CCFLog object.
       
   141 @leave KErrNoMemory 
       
   142 @internalTechnology */
       
   143 	{
       
   144 	CCFLogIf* This = new(ELeave) CCFLogIf;
       
   145 	CleanupStack::PushL(This);
       
   146 	This->ConstructL();
       
   147 	CleanupStack::Pop(This);
       
   148 	return This;
       
   149 	}
       
   150 
       
   151 EXPORT_C TInt CCFLogIf::Delete(CCFLogIf* aCFLogIf)
       
   152 /** Deletes a CCFLogIf object
       
   153 @return result KErrNone or KErrInUse
       
   154 @internalTechnology */
       
   155 	{
       
   156 	TInt result = KErrNone;
       
   157 	aCFLogIf->CFLog()->CsLock().Wait();
       
   158 	TInt count = aCFLogIf->CFLog()->UserCount();
       
   159 	aCFLogIf->CFLog()->CsLock().Signal();
       
   160 
       
   161 	if (count > 0)
       
   162 		{
       
   163 		__FLOG_STMT(TBuf8<KMaxTagLength> tag);
       
   164 		__FLOG_STMT(TBuf8<KMaxTagLength> subtag);
       
   165 		__FLOG_STMT(tag.Copy(KLogCommsFw));
       
   166 		__FLOG_STMT(subtag.Copy(KLogWarning));
       
   167 		__FLOG_STATIC1(tag, subtag, 
       
   168 			_L8("CCFLogIf::Delete **WARNING** there were still %d cflog sessions open"),
       
   169 			count);
       
   170 		result = KErrInUse;
       
   171 		}
       
   172 	delete aCFLogIf;
       
   173 	return result;
       
   174 	}
       
   175 
       
   176 void CCFLogIf::ConstructL()
       
   177 /** Second level constructor
       
   178 @leave KErrNoMemory
       
   179 @internalTechnology */
       
   180 	{
       
   181 	User::LeaveIfError(Dll::SetTls(this));
       
   182 	iCFLog = CCFLog::NewL();
       
   183 	}
       
   184 
       
   185 CCFLogIf::CCFLogIf() :
       
   186 	iCFLog(0)
       
   187 	{
       
   188 	}
       
   189 
       
   190 CCFLogIf::~CCFLogIf()
       
   191 	{
       
   192 	Dll::SetTls(NULL);
       
   193 	delete iCFLog;
       
   194 	}
       
   195 
       
   196 EXPORT_C void CCFLogIf::Panic(TCFLogPanic aPanic)
       
   197 /** Panic function
       
   198 @panic 
       
   199 @internalTechnology */
       
   200 	{
       
   201 	_LIT(tcflogger, "TCFLogger");
       
   202 	User::Panic(tcflogger, aPanic);	
       
   203 	}
       
   204 
       
   205 CCFLogIf* CheckContext()
       
   206 /** Function added to prevent CFLOG from panicking when Write functions are called
       
   207 and CFLOGGER is not installed (Other functions than Write are currently not affected).
       
   208 This is currently the case for Multimedia host which uses CommsFw but not CFLOG.
       
   209 Worth noting that this fix is temporary until CFLOGGER uses Utrace ;-) 
       
   210 @internalTechnology */
       
   211 	{
       
   212 	return static_cast<CCFLogIf*>(Dll::Tls());
       
   213 	}
       
   214 
       
   215 EXPORT_C CCFLogIf* CCFLogIf::Context()
       
   216 /** Used to reference the single process-wide CCFLogIf from different 
       
   217 threads+DLLs. Don't try to inline these - if TLS is in use then they 
       
   218 need to be in this DLL 
       
   219 @internalTechnology */
       
   220 	{ 
       
   221 	CCFLogIf* pCFLog = static_cast<CCFLogIf*>(Dll::Tls());
       
   222 	
       
   223 	// Check to make sure the TLS has been initialised correctly.
       
   224 	if( !pCFLog )
       
   225 		{
       
   226 		RDebug::Print( _L( "CCFLogIf::Context - the log interface was not set in the TLS.  This normally means that the logging version of cflog.dll has been mixed with a non-logging version of commsfw.dll/c32rootsrv.dll or logging calls have been made from a thread which has not called CCFLogIf::SetContext.  See CommsDebugUtility How-To Document FAQ section for details on enabling logging in a release build." ) );
       
   227 
       
   228 		Panic( ECFNoLogger );
       
   229 		}
       
   230 		
       
   231 	return pCFLog; 
       
   232 	}
       
   233 
       
   234 EXPORT_C void CCFLogIf::SetContext()
       
   235 /** A new thread/DLL needs to call this when the TLS handling is in use,
       
   236 ie in the thread startup function, having obtained a pointer to the 
       
   237 CCFLogIf somehow (eg caller passed in). Consider it as the 
       
   238 thread/dll introducing itself to the CFLogIf. "Pleased to meet you..." 
       
   239 @internalTechnology */
       
   240 	{ 
       
   241 	Dll::SetTls(this);
       
   242 	}
       
   243 
       
   244 EXPORT_C void CCFLogIf::Connect()
       
   245 /** Create a new connection cflogger.
       
   246 @internalTechnology */
       
   247 	{
       
   248 	CCFLogIf::Context()->iCFLog->DoConnect();
       
   249 	}
       
   250 	
       
   251 EXPORT_C void CCFLogIf::Close()
       
   252 /** Close an existing connection to cflogger
       
   253 @internalTechnology */
       
   254 	{
       
   255 	CCFLogIf::Context()->iCFLog->DoClose();
       
   256 	}
       
   257 	
       
   258 EXPORT_C void CCFLogIf::Write(const TDesC8& aSubsystem, const TDesC8& aComponent, const TDesC16& aText)
       
   259 /** Generates a log line and sends it to flogger.
       
   260 @internalTechnology */
       
   261 	{
       
   262 	// please see CheckContext() comment
       
   263 	CCFLogIf* context = CheckContext();
       
   264 	if (context)
       
   265 		{
       
   266 		context->iCFLog->DoWrite(aSubsystem, aComponent, aText);
       
   267 		}
       
   268 	}
       
   269 	
       
   270 EXPORT_C void CCFLogIf::WriteFormat(const TDesC8& aSubsystem, const TDesC8& aComponent, TRefByValue<const TDesC16> aFmt, ...)
       
   271 /** Generates a log line and sends it to flogger.
       
   272 @internalTechnology */
       
   273 	{
       
   274 	// please see CheckContext() comment
       
   275 	CCFLogIf* context = CheckContext();
       
   276 	if (context)
       
   277 		{
       
   278 		VA_LIST list;
       
   279 		VA_START(list, aFmt);
       
   280 		context->iCFLog->DoWriteFormat(aSubsystem, aComponent, aFmt, list);
       
   281 		}
       
   282 	}
       
   283 	
       
   284 EXPORT_C void CCFLogIf::WriteFormat(const TDesC8& aSubsystem, const TDesC8& aComponent, TRefByValue<const TDesC16> aFmt, VA_LIST& aList)
       
   285 /** Generates a log line and sends it to flogger.
       
   286 @internalTechnology */
       
   287 	{
       
   288 	// please see CheckContext() comment
       
   289 	CCFLogIf* context = CheckContext();
       
   290 	if (context)
       
   291 		{
       
   292 		context->iCFLog->DoWriteFormat(aSubsystem, aComponent, aFmt, aList);
       
   293 		}
       
   294 	}
       
   295 	
       
   296 EXPORT_C void CCFLogIf::Write(const TDesC8& aSubsystem, const TDesC8& aComponent, const TDesC8& aText)
       
   297 /** Generates a log line and sends it to flogger.
       
   298 @internalTechnology */
       
   299 	{
       
   300 	// please see CheckContext() comment
       
   301 	CCFLogIf* context = CheckContext();
       
   302 	if (context)
       
   303 		{
       
   304 		context->iCFLog->DoWrite(aSubsystem, aComponent, aText);
       
   305 		}
       
   306 	}
       
   307 	
       
   308 EXPORT_C void CCFLogIf::WriteFormat(const TDesC8& aSubsystem, const TDesC8& aComponent, TRefByValue<const TDesC8> aFmt,...)
       
   309 /** Generates a log line and sends it to flogger.
       
   310 @internalTechnology */
       
   311 	{
       
   312 	// please see CheckContext() comment
       
   313 	CCFLogIf* context = CheckContext();
       
   314 	if (context)
       
   315 		{
       
   316 		VA_LIST list;
       
   317 		VA_START(list, aFmt);
       
   318 		context->iCFLog->DoWriteFormat(aSubsystem, aComponent, aFmt, list);
       
   319 		}
       
   320 	}
       
   321 	
       
   322 EXPORT_C void CCFLogIf::WriteFormat(const TDesC8& aSubsystem, const TDesC8& aComponent, TRefByValue<const TDesC8> aFmt, VA_LIST& aList)
       
   323 /** Generates a log line and sends it to flogger.
       
   324 @internalTechnology */
       
   325 	{
       
   326 	// please see CheckContext() comment
       
   327 	CCFLogIf* context = CheckContext();
       
   328 	if (context)
       
   329 		{	
       
   330 		context->iCFLog->DoWriteFormat(aSubsystem, aComponent, aFmt, aList);
       
   331 		}
       
   332 	}
       
   333 	
       
   334 EXPORT_C void CCFLogIf::WriteBinary(const TDesC8& aSubsystem, const TDesC8& aComponent, const TDesC8& aData)
       
   335 /** Generates a log line and sends it to flogger.
       
   336 @internalTechnology */
       
   337 	{
       
   338 	// please see CheckContext() comment
       
   339 	CCFLogIf* context = CheckContext();
       
   340 	if (context)
       
   341 		{
       
   342 		context->iCFLog->DoWriteBinary(aSubsystem, aComponent, aData);
       
   343 		}
       
   344 	}
       
   345 	
       
   346 EXPORT_C void CCFLogIf::HexDump(const TDesC8& aSubsystem, const TDesC8& aComponent, const TText* aHeader, const TText* aMargin, const TUint8* aPtr, TInt aLen)
       
   347 /** Generates a log line and sends it to flogger.
       
   348 @internalTechnology */
       
   349 	{
       
   350 	CCFLogIf::Context()->iCFLog->DoHexDump(aSubsystem, aComponent, aHeader, aMargin, aPtr, aLen);
       
   351 	}
       
   352 
       
   353 CCFLog* CCFLogIf::CFLog()
       
   354 	{
       
   355 	return iCFLog;
       
   356 	}
       
   357 
       
   358 //--------------------
       
   359 TCFLogTags::TCFLogTags(const TBufC8<KMaxTagLength>& aComponent,
       
   360 					   const TBufC8<KMaxTagLength>& aSubSystem) :
       
   361 	iComponent(aComponent),
       
   362 	iSubSystem(aSubSystem)
       
   363 	{
       
   364 	}
       
   365 
       
   366 const TBufC8<KMaxTagLength>& TCFLogTags::Component() const 
       
   367 	{ 
       
   368 	return iComponent;
       
   369 	}
       
   370 
       
   371 const TBufC8<KMaxTagLength>& TCFLogTags::SubSystem() const
       
   372 	{
       
   373 	return iSubSystem;
       
   374 	}
       
   375 
       
   376 TBool TCFLogTags::Matches(const TCFLogTags& aTags1, const TCFLogTags& aTags2)
       
   377 	{
       
   378 	return aTags1.Component().Compare(aTags2.Component()) == 0 &&
       
   379 	   aTags1.SubSystem().Compare(aTags2.SubSystem()) == 0;
       
   380 	}
       
   381 
       
   382 
       
   383 //--------------------
       
   384 CCFLog::CCFLog() :
       
   385 	iUserCount(0),
       
   386 	iTags(KDefaultConnectionArrayLength),
       
   387 	iFloggers(KDefaultConnectionArrayLength)
       
   388 #ifdef __WIN32__
       
   389 #endif
       
   390 	{
       
   391 	iProcessHeap = &User::Heap();
       
   392 	}
       
   393 
       
   394 void CCFLog::ConstructL()
       
   395 	{
       
   396 	iCsLock.CreateLocal();
       
   397 
       
   398 	// construct initial cflogger will be first in session arrays
       
   399 	RFileLogger* defaultflogger;
       
   400 	User::LeaveIfError(GetFloggerPtr(KLogCommsFw, KCFLogOom, defaultflogger));
       
   401 	}
       
   402 
       
   403 CCFLog::~CCFLog()
       
   404 	{
       
   405 	iTags.Close();
       
   406 	TInt i;
       
   407 	for (i=0; i<iFloggers.Count(); i++)
       
   408 		{
       
   409 		iFloggers[i].Close();
       
   410 		}
       
   411 	iFloggers.Close();
       
   412 	iCsLock.Close();
       
   413 	}
       
   414 
       
   415 CCFLog* CCFLog::NewL()
       
   416 	{	
       
   417 	CCFLog* This = new(ELeave) CCFLog;
       
   418 	CleanupStack::PushL(This);
       
   419 	This->ConstructL();
       
   420 	CleanupStack::Pop(This);
       
   421 	return This;
       
   422 	}
       
   423 
       
   424 TInt CCFLog::GetFloggerPtr(const TDesC8& aSubsystem, const TDesC8& aComponent, RFileLogger*& aFlogger)
       
   425 	{
       
   426 	aFlogger = NULL;	// in case caller neglects error codes
       
   427 	TCFLogTags tags(aSubsystem, aComponent);
       
   428 	TInt error = KErrNone;
       
   429 
       
   430 	TInt index = iTags.Find(tags, TCFLogTags::Matches);
       
   431 	if (KErrNotFound == index)
       
   432 		{
       
   433 		// start CS
       
   434 		iCsLock.Wait();
       
   435 
       
   436 		// we must alloc stuff from our creator thread, otherwise if a thread
       
   437 		// exits, other threads will crash when they try to use the connection
       
   438 		RCFAllocator* threadHeap = User::SwitchHeap(iProcessHeap);
       
   439 
       
   440 		// create a new flogger and connect it using subsys and component tags
       
   441 		RFileLogger flogger;
       
   442 		error = flogger.Connect();
       
   443 		if (error == KErrNone)
       
   444 			{
       
   445 			error = iFloggers.Append(flogger);
       
   446 			
       
   447 			if (error == KErrNone)
       
   448 				{
       
   449 				index = iFloggers.Count()-1;
       
   450 				error = iFloggers[index].Share();
       
   451 				if (error == KErrNone)
       
   452 					{
       
   453 					error = iFloggers[index].SetLogTags(aSubsystem, aComponent);
       
   454 					if (error == KErrNone)
       
   455 						{
       
   456 						error = iTags.Append(tags);
       
   457 						}
       
   458 					}
       
   459 
       
   460 				// Upon error close & bin any new RFileLogger
       
   461 				if(error != KErrNone)
       
   462 					{
       
   463 					iFloggers[index].Close();
       
   464 					iFloggers.Remove(index);
       
   465 					index = KErrNotFound;
       
   466 					}
       
   467 				}
       
   468 			else
       
   469 				{
       
   470 				flogger.Close();
       
   471 				}
       
   472 			}
       
   473 		// put heap back
       
   474 		User::SwitchHeap(threadHeap);
       
   475 		// end CS
       
   476 		iCsLock.Signal();
       
   477 		}
       
   478 	if(index != KErrNotFound)
       
   479 		{
       
   480 		aFlogger = &iFloggers[index];
       
   481 #if defined(__WINS__)
       
   482 		TUint32 win32Thread;
       
   483 		if(iWin32Threads.CheckWin32Thread(win32Thread, iProcessHeap))
       
   484 			{
       
   485 			_LIT8(KDebugExtra, "DebugExtra");
       
   486 			_LIT8(KDebugThread, "Thread");
       
   487 			// This recurses, but safely as we've already added the thread so won't log again
       
   488 			RThread epocThread;
       
   489 			TFullName fullName = epocThread.FullName();
       
   490 			TBuf8<sizeof(TFullName) / sizeof(TText)> printableName;
       
   491 			printableName.Copy(fullName);
       
   492 			DoWriteFormat(KDebugExtra, KDebugThread, _L8("Win32 thread 0x%x (%d) (%S) "), win32Thread, win32Thread, &printableName);
       
   493 			}
       
   494 #endif
       
   495 		}
       
   496 	return error;
       
   497 	}
       
   498 
       
   499 TInt CCFLog::DoConnect()
       
   500 	{
       
   501 	return User::LockedInc(iUserCount) + 1;
       
   502 	}
       
   503 
       
   504 TInt CCFLog::DoClose()
       
   505 	{
       
   506 	__ASSERT_ALWAYS(iUserCount>0, CCFLogIf::Panic(ECFUserCountInvalid));
       
   507 	return User::LockedDec(iUserCount) - 1;
       
   508 	}
       
   509 
       
   510 void CCFLog::DoWrite(const TDesC8& aSubsystem, const TDesC8& aComponent, const TDesC16& aText)
       
   511 	{
       
   512 	RFileLogger *flogger;
       
   513 	if(GetFloggerPtr(aSubsystem, aComponent, flogger) == KErrNone)
       
   514 		{
       
   515 		flogger->Write(aText);
       
   516 		}
       
   517 	}
       
   518 
       
   519 void CCFLog::DoWriteFormat(const TDesC8& aSubsystem, const TDesC8& aComponent, TRefByValue<const TDesC16> aFmt,...)
       
   520 	{
       
   521 	VA_LIST list;
       
   522 	VA_START(list, aFmt);
       
   523 
       
   524 	RFileLogger *flogger;
       
   525 	if(GetFloggerPtr(aSubsystem, aComponent, flogger) == KErrNone)
       
   526 		{
       
   527 		flogger->WriteFormat(aFmt, list);
       
   528 		}
       
   529 	}
       
   530 
       
   531 void CCFLog::DoWriteFormat(const TDesC8& aSubsystem, const TDesC8& aComponent, TRefByValue<const TDesC16> aFmt, VA_LIST& aList)
       
   532 	{
       
   533 	RFileLogger *flogger;
       
   534 	if(GetFloggerPtr(aSubsystem, aComponent, flogger) == KErrNone)
       
   535 		{
       
   536 		flogger->WriteFormat(aFmt, aList);
       
   537 		}
       
   538 	}
       
   539 
       
   540 void CCFLog::DoWrite(const TDesC8& aSubsystem, const TDesC8& aComponent, const TDesC8& aText)
       
   541 	{
       
   542 	RFileLogger *flogger;
       
   543 	if(GetFloggerPtr(aSubsystem, aComponent, flogger) == KErrNone)
       
   544 		{
       
   545 		flogger->Write(aText);
       
   546 		}
       
   547 	}
       
   548 
       
   549 void CCFLog::DoWriteFormat(const TDesC8& aSubsystem, const TDesC8& aComponent, TRefByValue<const TDesC8> aFmt,...)
       
   550 	{
       
   551 	VA_LIST list;
       
   552 	VA_START(list, aFmt);
       
   553 
       
   554 	RFileLogger *flogger;
       
   555 	if(GetFloggerPtr(aSubsystem, aComponent, flogger) == KErrNone)
       
   556 		{
       
   557 		flogger->WriteFormat(aFmt, list);
       
   558 		}
       
   559 	}
       
   560 
       
   561 void CCFLog::DoWriteFormat(const TDesC8& aSubsystem, const TDesC8& aComponent, TRefByValue<const TDesC8> aFmt, VA_LIST& aList)
       
   562 	{
       
   563 	RFileLogger *flogger;
       
   564 	if(GetFloggerPtr(aSubsystem, aComponent, flogger) == KErrNone)
       
   565 		{
       
   566 		flogger->WriteFormat(aFmt, aList);
       
   567 		}
       
   568 	}
       
   569 
       
   570 void CCFLog::DoWriteBinary(const TDesC8& aSubsystem, const TDesC8& aComponent, const TDesC8& aData)
       
   571 	{
       
   572 	RFileLogger *flogger;
       
   573 	if(GetFloggerPtr(aSubsystem, aComponent, flogger) == KErrNone)
       
   574 		{
       
   575 		flogger->WriteBinary(aData);
       
   576 		}
       
   577 	}
       
   578 
       
   579 void CCFLog::DoHexDump(const TDesC8& aSubsystem, const TDesC8& aComponent, const TText* aHeader, const TText* aMargin, const TUint8* aPtr, TInt aLen)
       
   580 	{
       
   581 	RFileLogger *flogger;
       
   582 	if(GetFloggerPtr(aSubsystem, aComponent, flogger) == KErrNone)
       
   583 		{
       
   584 		flogger->HexDump(aHeader, aMargin, aPtr, aLen);
       
   585 		}
       
   586 	}
       
   587 
       
   588 TInt CCFLog::UserCount()
       
   589 	{
       
   590 	return iUserCount;
       
   591 	}
       
   592 
       
   593 CCFLog::RCFLockType& CCFLog::CsLock()
       
   594 	{
       
   595 	return iCsLock;		//lint !e1536
       
   596 	}
       
   597 
       
   598 #else	 // defined(__CFLOG_ACTIVE)
       
   599 
       
   600 EXPORT_C CCFLogIf* CCFLogIf::NewL()
       
   601 /** Empty implementation to keep exports for all builds
       
   602 @panic ECFNoLogger if there is no flogger present
       
   603 @return NULL
       
   604 @internalTechnology */
       
   605 	{
       
   606 //	Panic(ECFNoLogger);
       
   607 	return NULL;
       
   608 	}
       
   609 
       
   610 EXPORT_C TInt CCFLogIf::Delete(CCFLogIf*)
       
   611 /** Empty implementation to keep exports for all builds
       
   612 @panic ECFNoLogger if there is no flogger present
       
   613 @return NULL
       
   614 @internalTechnology */
       
   615 	{
       
   616 //	Panic(ECFNoLogger);
       
   617 	return 0;
       
   618 	}
       
   619 
       
   620 //EXPORT_C void CCFLogIf::Panic(TCFLogPanic aPanic)
       
   621 EXPORT_C void CCFLogIf::Panic(TCFLogPanic)
       
   622 /** Empty implementation to keep exports for all builds
       
   623 @panic ECFNoLogger if there is no flogger present
       
   624 @return NULL
       
   625 @internalTechnology */
       
   626 	{
       
   627 //	_LIT(tcflogger, "TCFLogger");
       
   628 //	User::Panic(tcflogger, aPanic);	
       
   629 	}
       
   630 
       
   631 	
       
   632 EXPORT_C CCFLogIf* CCFLogIf::Context()
       
   633 /** Empty implementation to keep exports for all builds
       
   634 @panic ECFNoLogger if there is no flogger present
       
   635 @return NULL
       
   636 @internalTechnology */
       
   637 	{ 
       
   638 //	Panic(ECFNoLogger);
       
   639 	return NULL;
       
   640 	}
       
   641 
       
   642 EXPORT_C void CCFLogIf::SetContext()
       
   643 /** Empty implementation to keep exports for all builds
       
   644 @panic ECFNoLogger if there is no flogger present
       
   645 @return NULL
       
   646 @internalTechnology */
       
   647 	{ 
       
   648 //	Panic(ECFNoLogger);
       
   649 	}
       
   650 
       
   651 EXPORT_C void CCFLogIf::Connect()
       
   652 /** Empty implementation to keep exports for all builds
       
   653 @panic ECFNoLogger if there is no flogger present
       
   654 @return NULL
       
   655 @internalTechnology */
       
   656 	{
       
   657 //	Panic(ECFNoLogger);
       
   658 	}
       
   659 	
       
   660 EXPORT_C void CCFLogIf::Close()
       
   661 /** Empty implementation to keep exports for all builds
       
   662 @panic ECFNoLogger if there is no flogger present
       
   663 @return NULL
       
   664 @internalTechnology */
       
   665 	{
       
   666 //	Panic(ECFNoLogger);
       
   667 	}
       
   668 	
       
   669 EXPORT_C void CCFLogIf::Write(const TDesC8&, const TDesC8&, const TDesC16&)
       
   670 /** Empty implementation to keep exports for all builds
       
   671 @panic ECFNoLogger if there is no flogger present
       
   672 @return NULL
       
   673 @internalTechnology */
       
   674 	{
       
   675 //	Panic(ECFNoLogger);
       
   676 	}
       
   677 	
       
   678 EXPORT_C void CCFLogIf::WriteFormat(const TDesC8&, const TDesC8&, TRefByValue<const TDesC16>, ...)
       
   679 /** Empty implementation to keep exports for all builds
       
   680 @panic ECFNoLogger if there is no flogger present
       
   681 @return NULL
       
   682 @internalTechnology */
       
   683 	{
       
   684 //	Panic(ECFNoLogger);
       
   685 	}
       
   686 	
       
   687 EXPORT_C void CCFLogIf::WriteFormat(const TDesC8&, const TDesC8&, TRefByValue<const TDesC16>, VA_LIST&)
       
   688 /** Empty implementation to keep exports for all builds
       
   689 @panic ECFNoLogger if there is no flogger present
       
   690 @return NULL
       
   691 @internalTechnology */
       
   692 	{
       
   693 //	Panic(ECFNoLogger);
       
   694 	}
       
   695 	
       
   696 EXPORT_C void CCFLogIf::Write(const TDesC8&, const TDesC8&, const TDesC8&)
       
   697 /** Empty implementation to keep exports for all builds
       
   698 @panic ECFNoLogger if there is no flogger present
       
   699 @return NULL
       
   700 @internalTechnology */
       
   701 	{
       
   702 //	Panic(ECFNoLogger);
       
   703 	}
       
   704 	
       
   705 EXPORT_C void CCFLogIf::WriteFormat(const TDesC8&, const TDesC8&, TRefByValue<const TDesC8>, ...)
       
   706 /** Empty implementation to keep exports for all builds
       
   707 @panic ECFNoLogger if there is no flogger present
       
   708 @return NULL
       
   709 @internalTechnology */
       
   710 	{
       
   711 //	Panic(ECFNoLogger);
       
   712 	}
       
   713 	
       
   714 EXPORT_C void CCFLogIf::WriteFormat(const TDesC8&, const TDesC8&, TRefByValue<const TDesC8>, VA_LIST&)
       
   715 /** Empty implementation to keep exports for all builds
       
   716 @panic ECFNoLogger if there is no flogger present
       
   717 @return NULL
       
   718 @internalTechnology */
       
   719 	{
       
   720 //	Panic(ECFNoLogger);
       
   721 	}
       
   722 	
       
   723 EXPORT_C void CCFLogIf::WriteBinary(const TDesC8&, const TDesC8&, const TDesC8&)
       
   724 /** Empty implementation to keep exports for all builds
       
   725 @panic ECFNoLogger if there is no flogger present
       
   726 @return NULL
       
   727 @internalTechnology */
       
   728 	{
       
   729 //	Panic(ECFNoLogger);
       
   730 	}
       
   731 	
       
   732 EXPORT_C void CCFLogIf::HexDump(const TDesC8&, const TDesC8&, const TText*, const TText*, const TUint8*, TInt)
       
   733 /** Empty implementation to keep exports for all builds
       
   734 @panic ECFNoLogger if there is no flogger present
       
   735 @return NULL
       
   736 @internalTechnology */
       
   737 	{
       
   738 //	Panic(ECFNoLogger);
       
   739 	}
       
   740 
       
   741 
       
   742 #endif	// defined(__CFLOG_ACTIVE)
       
   743 
       
   744