libraries/clogger/src/Flogger.cpp
changeset 0 7f656887cf89
equal deleted inserted replaced
-1:000000000000 0:7f656887cf89
       
     1 // Flogger.cpp
       
     2 // 
       
     3 // Copyright (c) 2006 - 2010 Accenture. All rights reserved.
       
     4 // This component and the accompanying materials are made available
       
     5 // under the terms of the "Eclipse Public License v1.0"
       
     6 // which accompanies this distribution, and is available
       
     7 // at the URL "http://www.eclipse.org/legal/epl-v10.html".
       
     8 // 
       
     9 // Initial Contributors:
       
    10 // Accenture - Initial contribution
       
    11 //
       
    12 
       
    13 #include <e32base.h>
       
    14 #include <fshell/clogger.h>
       
    15 #include "cliserv.h"
       
    16 
       
    17 // This file is shared between building shims for traditional flogger and comms debug util
       
    18 // Bits specific to one or the other are guarded with  __CDU__
       
    19 
       
    20 #ifdef __CDU__
       
    21 
       
    22 #define __FLOG_SUPPRESS_REL_WARNING
       
    23 #define __FLOG_ACTIVE
       
    24 #include <comms-infras/commsdebugutility.h>
       
    25 #define iPtr ((RClogger*)iLoggerBody)
       
    26 #define Connected() (iPtr && iPtr->Handle())
       
    27 #define DoClose() { if (iPtr) { iPtr->Close(); delete iPtr; iLoggerBody = NULL; } }
       
    28 
       
    29 #else
       
    30 
       
    31 #include <flogger.h>
       
    32 #define iPtr (*((RClogger**)&iFormatter))
       
    33 #define Connected() (iPtr && iPtr->Handle())
       
    34 #define DoClose() { if (iPtr) { iPtr->Close(); delete iPtr; } }
       
    35 
       
    36 #endif
       
    37 
       
    38 #define iClogger (*iPtr)
       
    39 #define FlogPtr(clogPtr) ((RFloggerClogger*)clogPtr)
       
    40 
       
    41 // declares RClogger* clogger
       
    42 #define CheckConnected(aDir, aPath)                            \
       
    43 	RClogger _cloggerHandle;                                   \
       
    44 	RClogger* clogger = &_cloggerHandle;                       \
       
    45 	GetTls(clogger, ETrue, &aDir, &aPath, ETrue, NULL);        \
       
    46 	if (!clogger) return
       
    47 
       
    48 #define CheckConnected8(aDir, aPath)                           \
       
    49 	RClogger _cloggerHandle;                                   \
       
    50 	RClogger* clogger = &_cloggerHandle;                       \
       
    51 	GetTls(clogger, ETrue, &aDir, &aPath, EFalse, NULL);       \
       
    52 	if (!clogger) return
       
    53 
       
    54 /*
       
    55 #define GetTlsOrConnect(aTag)                                  \
       
    56 	RClogger _cloggerHandle;                                   \
       
    57 	RClogger* clogger = &_cloggerHandle;                       \
       
    58 	TInt err;                                                  \
       
    59 	TBool isHandle = GetTls(clogger, ETrue, &aTag, &err)
       
    60 */
       
    61 
       
    62 #define GetTlsOrNull()                                         \
       
    63 	RClogger _cloggerHandle;                                   \
       
    64 	RClogger* clogger = &_cloggerHandle;                       \
       
    65 TBool isHandle = ::GetTls(clogger, EFalse, &KNullDesC, &KNullDesC, ETrue, NULL)
       
    66 
       
    67 #define KDontAllocateWhileLogging 0x20000000
       
    68 
       
    69 static TBool GetTls(RClogger*& aClogger, TBool aAutoConnect, const TAny* aTag, const TAny* aSubTag, TBool aWide, TInt* aError);
       
    70 
       
    71 // Need these because flogger has a single-argument overload that doesn't have a format applied over it, and clogger doesn't
       
    72 _LIT8(KEsc8, "%S");
       
    73 _LIT(KEsc, "%S");
       
    74 
       
    75 #define iBody (*(RCloggerBody*)&iPimpl)
       
    76 
       
    77 #ifdef _DEBUG
       
    78 // Close the session after every call in debug builds, to avoid heap-check and handle-check failures
       
    79 #define STATICCLOSE() RFloggerClogger::FloggerStaticClose()
       
    80 #else
       
    81 #define STATICCLOSE()
       
    82 #endif
       
    83 
       
    84 class RFloggerClogger : public RClogger
       
    85 	{
       
    86 public:
       
    87 	TUint& Flags()
       
    88 		{
       
    89 		return iFlags;
       
    90 		}
       
    91 
       
    92 	TInt FloggerConnect(const TDesC& aDir, const TDesC& aName)
       
    93 		{
       
    94 		TAny* arg1 = NULL;
       
    95 		TInt err = Reserved(0xF10C10, arg1, NULL); // Does the connect
       
    96 		if (!err)
       
    97 			{
       
    98 			err = DoSetTags(aDir, aName);
       
    99 			}
       
   100 		return err;
       
   101 		}
       
   102 
       
   103 	TInt FloggerConnect(const TDesC8& aDir, const TDesC8& aName)
       
   104 		{
       
   105 		TAny* arg1 = NULL;
       
   106 		TInt err = Reserved(0xF10C10, arg1, NULL); // Does the connect
       
   107 		if (!err)
       
   108 			{
       
   109 			err = DoSetTags8(aDir, aName);
       
   110 			}
       
   111 		return err;
       
   112 		}
       
   113 
       
   114 	TInt DoSetTags(const TDesC& aDir, const TDesC& aName)
       
   115 		{
       
   116 		//TPtrC name(aName);
       
   117 		//_LIT(KDotTxt, ".txt");
       
   118 		//_LIT(KDotLog, ".log");
       
   119 		//if (name.Right(KDotTxt().Length()) == KDotTxt) name.Set(name.Left(name.Length()-KDotTxt().Length()));
       
   120 		//else if (name.Right(KDotLog().Length()) == KDotLog) name.Set(name.Left(name.Length()-KDotLog().Length()));
       
   121 		TPckg<TUint32> enabledPkg(iEnabled);
       
   122 		TInt result = SendReceive(ESetTag, TIpcArgs(&aDir, &aName, &enabledPkg));
       
   123 		if (result >= 0)
       
   124 			{
       
   125 			iSequence = result;
       
   126 			return KErrNone;
       
   127 			}
       
   128 		else
       
   129 			{
       
   130 			return result;
       
   131 			}
       
   132 		}
       
   133 
       
   134 	TInt DoSetTags8(const TDesC8& aDir, const TDesC8& aName)
       
   135 		{
       
   136 		//TPtrC8 name(aName);
       
   137 		//_LIT8(KDotTxt, ".txt");
       
   138 		//_LIT8(KDotLog, ".log");
       
   139 		//if (name.Right(KDotTxt().Length()) == KDotTxt) name.Set(name.Left(name.Length()-KDotTxt().Length()));
       
   140 		//else if (name.Right(KDotLog().Length()) == KDotLog) name.Set(name.Left(name.Length()-KDotLog().Length()));
       
   141 		TPckg<TUint32> enabledPkg(iEnabled);
       
   142 		TInt result = SendReceive(ESetTag8, TIpcArgs(&aDir, &aName, &enabledPkg));
       
   143 		if (result >= 0)
       
   144 			{
       
   145 			iSequence = result;
       
   146 			return KErrNone;
       
   147 			}
       
   148 		else
       
   149 			{
       
   150 			return result;
       
   151 			}
       
   152 		}
       
   153 
       
   154 	static void FloggerStaticClose()
       
   155 		{
       
   156 		GetTlsOrNull();
       
   157 		if (clogger)
       
   158 			{
       
   159 			clogger->Close();
       
   160 			if (!isHandle)
       
   161 				{
       
   162 				delete clogger;
       
   163 				}
       
   164 			Dll::SetTls(NULL);
       
   165 			Dll::FreeTls();
       
   166 			}
       
   167 		}
       
   168 
       
   169 	void HexDump16(const TDesC16& aHeader, const TDesC8& aData)
       
   170 		{
       
   171 		SendReceive(2002, TIpcArgs(&aHeader, &aData, User::NTickCount(), RClogger::EAllEnabled));
       
   172 		}
       
   173 	};
       
   174 
       
   175 static TBool GetTls(RClogger*& aClogger, TBool aAutoConnect, const TAny* aTag, const TAny* aSubTag, TBool aWide, TInt* aError)
       
   176 	{
       
   177 	TAny* tls = Dll::Tls();
       
   178 	if ((TUint)tls & 1)
       
   179 		{
       
   180 		// Then it's a handle
       
   181 		aClogger->SetHandle((TInt)((TUint)tls >> 1));
       
   182 		return ETrue;
       
   183 		}
       
   184 	else if (tls)
       
   185 		{
       
   186 		// Then it's a pointer
       
   187 		aClogger = (RClogger*)tls;
       
   188 		return EFalse;
       
   189 		}
       
   190 	else if (aAutoConnect)
       
   191 		{
       
   192 		//TInt err = aClogger->Connect(aTag ? *aTag : KNullDesC);
       
   193 		TInt err;
       
   194 		if (aWide)
       
   195 			{
       
   196 			err = FlogPtr(aClogger)->FloggerConnect(*(const TDesC*)aTag, *(const TDesC*)aSubTag);
       
   197 			}
       
   198 		else
       
   199 			{
       
   200 			err = FlogPtr(aClogger)->FloggerConnect(*(const TDesC8*)aTag, *(const TDesC8*)aSubTag);
       
   201 			}
       
   202 		
       
   203 		if (err)
       
   204 			{
       
   205 			if (aError) *aError = err;
       
   206 			aClogger = NULL;
       
   207 			return ETrue;
       
   208 			}
       
   209 		if ((aClogger->Handle() & 0x80000000) != 0)
       
   210 			{
       
   211 			__ASSERT_DEBUG(EFalse, User::Panic(_L("HandleTooBig"), 0));
       
   212 			err = KErrOverflow;
       
   213 			}
       
   214 
       
   215 		if (!err)
       
   216 			{
       
   217 			err = Dll::SetTls((TAny*) ((aClogger->Handle() << 1) | 1));
       
   218 			}
       
   219 
       
   220 		if (err)
       
   221 			{
       
   222 			aClogger->Close();
       
   223 			if (aError) *aError = err;
       
   224 			aClogger = NULL;
       
   225 			}
       
   226 		return ETrue;
       
   227 		}
       
   228 	else
       
   229 		{
       
   230 		aClogger = NULL;
       
   231 		return ETrue;
       
   232 		}
       
   233 	}
       
   234 
       
   235 EXPORT_C RFileLogger::RFileLogger()
       
   236 	{
       
   237 	Mem::FillZ(this, sizeof(RFileLogger));
       
   238 	}
       
   239 
       
   240 EXPORT_C RFileLogger::~RFileLogger()
       
   241 	{
       
   242 	}
       
   243 
       
   244 EXPORT_C TVersion RFileLogger::Version() const
       
   245 	{
       
   246 	return TVersion(1, 0, 20);
       
   247 	}
       
   248 
       
   249 EXPORT_C TInt RFileLogger::Connect()
       
   250 	{
       
   251 	if (Connected())
       
   252 		{
       
   253 		return KErrAlreadyExists;
       
   254 		}
       
   255 
       
   256 	#ifdef __CDU__
       
   257 		iLoggerBody = (RFileLoggerBody*)new RClogger();
       
   258 		if (!iLoggerBody) return KErrNoMemory;
       
   259 	#else
       
   260 		iPtr = new RClogger();
       
   261 		if (!iPtr) return KErrNoMemory;
       
   262 	#endif
       
   263 
       
   264 	TInt err = iClogger.Connect();
       
   265 	/*
       
   266 	#ifdef _DEBUG
       
   267 		if (!err)
       
   268 			{
       
   269 			// Don't cache client buffers in debug mode (so we will pass UDEB heap check macros)
       
   270 			FlogPtr(iPtr)->Flags() &= ~RClogger::ECacheClientBuffers;
       
   271 			}
       
   272 	#endif
       
   273 	*/
       
   274 
       
   275 	#if !defined(__CDU__) && defined(_DEBUG)
       
   276 		if (err == KErrNone)
       
   277 			{
       
   278 			SetHandle(iClogger.Handle()); // We do this so that when Close() is called, it cleans up the clogger interface. And we do that because we can't override Close(), and if the session doesn't get closed somehow, we'll fail CONE's handle check in debug builds
       
   279 			}
       
   280 	#endif
       
   281 	if (!err)
       
   282 		{
       
   283 		iClogger.SetLogBehaviour(0 /*RClogger::EMonitorTagState*/); // Don't set EUseHeapBuffer because then we won't be thread-safe
       
   284 		}
       
   285 	else
       
   286 		{
       
   287 		DoClose();
       
   288 		}
       
   289 	return err;
       
   290 	}
       
   291 
       
   292 EXPORT_C void RFileLogger::SetDateAndTime(TBool /*aUseDate*/, TBool /*aUseTime*/)
       
   293 	{
       
   294 	// Has no real meaning in clogger
       
   295 	}
       
   296 
       
   297 EXPORT_C void RFileLogger::CreateLog(const TDesC& aDir, const TDesC& aName, TFileLoggingMode /*aMode*/)
       
   298 	{
       
   299 	TInt err;
       
   300 	if (Connected())
       
   301 		{
       
   302 		err = FlogPtr(&iClogger)->DoSetTags(aDir, aName);
       
   303 		}
       
   304 	else
       
   305 		{
       
   306 		err = KErrNotFound;
       
   307 		}
       
   308 	#ifdef __CDU__
       
   309 		if (err) {} //Like CDU, ignore errors in legacy methods. This construction shuts up RVCT
       
   310 	#else
       
   311 		 iLastError = err;
       
   312 	#endif
       
   313 
       
   314 	}
       
   315 
       
   316 EXPORT_C void RFileLogger::CloseLog()
       
   317 	{
       
   318 	// Has no meaning in clogger terms
       
   319 	}
       
   320 
       
   321 EXPORT_C void RFileLogger::Write(const TDesC16& aText)
       
   322 	{
       
   323 	if (!Connected()) return; // Be compatible with CDU and flogger in terms of not crashing
       
   324 	iClogger.Log(RClogger::EAllEnabled, KEsc, &aText);
       
   325 	}
       
   326 
       
   327 EXPORT_C void RFileLogger::WriteFormat(TRefByValue<const TDesC16> aFmt,...)
       
   328 	{
       
   329 	if (!Connected()) return; // Be compatible with CDU and flogger in terms of not crashing
       
   330 	VA_LIST args;
       
   331 	VA_START(args, aFmt);
       
   332 	iClogger.LogList(RClogger::EAllEnabled, aFmt, args);
       
   333 	VA_END(args);
       
   334 	}
       
   335 
       
   336 EXPORT_C void RFileLogger::WriteFormat(TRefByValue<const TDesC16> aFmt, VA_LIST& aList)
       
   337 	{
       
   338 	if (!Connected()) return; // Be compatible with CDU and flogger in terms of not crashing
       
   339 	iClogger.LogList(RClogger::EAllEnabled, aFmt, aList);
       
   340 	}
       
   341 
       
   342 EXPORT_C void RFileLogger::Write(const TDesC8& aText)
       
   343 	{
       
   344 	if (!Connected()) return; // Be compatible with CDU and flogger in terms of not crashing
       
   345 	iClogger.Log(RClogger::EAllEnabled, KEsc8, &aText);
       
   346 	}
       
   347 
       
   348 EXPORT_C void RFileLogger::WriteFormat(TRefByValue<const TDesC8> aFmt,...)
       
   349 	{
       
   350 	if (!Connected()) return; // Be compatible with CDU and flogger in terms of not crashing
       
   351 	VA_LIST args;
       
   352 	VA_START(args, aFmt);
       
   353 	iClogger.LogList(RClogger::EAllEnabled, aFmt, args);
       
   354 	VA_END(args);
       
   355 	}
       
   356 
       
   357 EXPORT_C void RFileLogger::WriteFormat(TRefByValue<const TDesC8> aFmt, VA_LIST& aList)
       
   358 	{
       
   359 	if (!Connected()) return; // Be compatible with CDU and flogger in terms of not crashing
       
   360 	iClogger.LogList(RClogger::EAllEnabled, aFmt, aList);
       
   361 	}
       
   362 
       
   363 EXPORT_C void RFileLogger::HexDump(const TText* aHeader, const TText* /*aMargin*/, const TUint8* aPtr, TInt aLen)
       
   364 	{
       
   365 	if (!Connected()) return; // Be compatible with CDU and flogger in terms of not crashing
       
   366 	TPtrC16 header;
       
   367 	if (aHeader)
       
   368 		{
       
   369 		header.Set(aHeader, User::StringLength(aHeader));
       
   370 		}
       
   371 	const TPtrC8 data(aPtr, aLen);
       
   372 	FlogPtr(iPtr)->HexDump16(header, data);
       
   373 	}
       
   374 
       
   375 EXPORT_C TInt RFileLogger::LastError() const
       
   376 	{
       
   377 	#ifdef __CDU__
       
   378 		return KErrNone;
       
   379 	#else
       
   380 		return iLastError;
       
   381 	#endif
       
   382 	}
       
   383 
       
   384 EXPORT_C TBool RFileLogger::LogValid() const
       
   385 	{
       
   386 	return ETrue;
       
   387 	}
       
   388 
       
   389 // The static functions
       
   390 EXPORT_C void RFileLogger::Write(const TDesC& aDir, const TDesC& aName, TFileLoggingMode /*aMode*/, const TDesC16& aText)
       
   391 	{
       
   392 	CheckConnected(aDir, aName);
       
   393 	clogger->Log(KEsc, &aText);
       
   394 
       
   395 	STATICCLOSE();
       
   396 	}
       
   397 
       
   398 EXPORT_C void RFileLogger::WriteFormat(const TDesC& aDir, const TDesC& aName, TFileLoggingMode /*aMode*/, TRefByValue<const TDesC16> aFmt,...)
       
   399 	{
       
   400 	CheckConnected(aDir, aName);
       
   401 	VA_LIST args;
       
   402 	VA_START(args, aFmt);
       
   403 	clogger->LogList(aFmt, args);
       
   404 	VA_END(args);
       
   405 
       
   406 	STATICCLOSE();
       
   407 	}
       
   408 
       
   409 EXPORT_C void RFileLogger::WriteFormat(const TDesC& aDir, const TDesC& aName, TFileLoggingMode /*aMode*/, TRefByValue<const TDesC16> aFmt, VA_LIST& aList)
       
   410 	{
       
   411 	CheckConnected(aDir, aName);
       
   412 	clogger->LogList(aFmt, aList);
       
   413 
       
   414 	STATICCLOSE();
       
   415 	}
       
   416 
       
   417 EXPORT_C void RFileLogger::Write(const TDesC& aDir, const TDesC& aName, TFileLoggingMode /*aMode*/, const TDesC8& aText)
       
   418 	{
       
   419 	CheckConnected(aDir, aName);
       
   420 	clogger->Log(KEsc8, &aText);
       
   421 
       
   422 	STATICCLOSE();
       
   423 	}
       
   424 
       
   425 EXPORT_C void RFileLogger::WriteFormat(const TDesC& aDir, const TDesC& aName, TFileLoggingMode /*aMode*/, TRefByValue<const TDesC8> aFmt,...)
       
   426 	{
       
   427 	CheckConnected(aDir, aName);
       
   428 	VA_LIST args;
       
   429 	VA_START(args, aFmt);
       
   430 	clogger->LogList(aFmt, args);
       
   431 	VA_END(args);
       
   432 
       
   433 	STATICCLOSE();
       
   434 	}
       
   435 
       
   436 EXPORT_C void RFileLogger::WriteFormat(const TDesC& aDir, const TDesC& aName, TFileLoggingMode /*aMode*/, TRefByValue<const TDesC8> aFmt, VA_LIST& aList)
       
   437 	{
       
   438 	CheckConnected(aDir, aName);
       
   439 	clogger->LogList(aFmt, aList);
       
   440 
       
   441 	STATICCLOSE();
       
   442 	}
       
   443 
       
   444 EXPORT_C void RFileLogger::HexDump(const TDesC& aDir, const TDesC& aName, TFileLoggingMode /*aMode*/, const TText* aHeader, const TText* /*aMargin*/, const TUint8* aPtr, TInt aLen)
       
   445 	{
       
   446 	CheckConnected(aDir, aName);
       
   447 	const TPtrC16 header(aHeader);
       
   448 	const TPtrC8 data(aPtr, aLen);
       
   449 
       
   450 	FlogPtr(clogger)->HexDump16(header, data);
       
   451 	}
       
   452 
       
   453 // Boring stuff
       
   454 
       
   455 #ifndef __CDU__
       
   456 
       
   457 TLogFormatter::TLogFormatter() {}
       
   458 TLogFile::TLogFile() {}
       
   459 void TLogFormatter8Overflow::Overflow(TDes8& /*aDes*/) {}
       
   460 void TLogFormatter16Overflow::Overflow(TDes16& /*aDes*/) {}
       
   461 EXPORT_C TInt FLogger::Run(FLogger::TSignal& /*aSignal*/)
       
   462 	{
       
   463 	return KErrNotSupported;
       
   464 	}
       
   465 
       
   466 #endif
       
   467 
       
   468 #ifdef __CDU__
       
   469 
       
   470 // Some functions new in CDU
       
   471 
       
   472 EXPORT_C void RFileLogger::Close()
       
   473 	{
       
   474 	DoClose();
       
   475 	}
       
   476 
       
   477 EXPORT_C void ClientRunStubOrdinal1()
       
   478 	{
       
   479 	}
       
   480 
       
   481 EXPORT_C TInt RFileLogger::ClearLog()
       
   482 	{
       
   483 	if (!Connected()) return KErrNone; // Be compatible with CDU and flogger in terms of not crashing
       
   484 	return iClogger.Rotate(); // Close enough
       
   485 	}
       
   486 
       
   487 EXPORT_C TInt RFileLogger::SetLogTags(const TDesC8& aSubsystem, const TDesC8& aComponent)
       
   488 	{
       
   489 	return FlogPtr(iPtr)->DoSetTags8(aSubsystem, aComponent);
       
   490 	}
       
   491 
       
   492 EXPORT_C void RFileLogger::__DbgShutDownServer()
       
   493 	{
       
   494 	// Why bother supporting this?
       
   495 	}
       
   496 
       
   497 EXPORT_C void RFileLogger::__DbgSetHeapFailure(TInt /*aFailAfter*/)
       
   498 	{
       
   499 	// See above...
       
   500 	}
       
   501 
       
   502 EXPORT_C void RFileLogger::WriteBinary(const TDesC8& aData)
       
   503 	{
       
   504 	if (!Connected()) return; // Be compatible with CDU and flogger in terms of not crashing
       
   505 	iClogger.Log(KEsc8, &aData);
       
   506 	}
       
   507 
       
   508 EXPORT_C void RFileLogger::HexDump(const TDesC8& aSubsystem, const TDesC8& aComponent, const TDesC8& aData, const TDesC8& aHeader)
       
   509 	{
       
   510 	CheckConnected8(aSubsystem, aComponent);
       
   511 
       
   512 	clogger->HexDump(aHeader, aData);
       
   513 	}
       
   514 
       
   515 EXPORT_C void RFileLogger::HexDump(const TDesC8& aData, const TDesC8& aHeader)
       
   516 	{
       
   517 	if (!Connected()) return; // Be compatible with CDU and flogger in terms of not crashing
       
   518 	iClogger.HexDump(aHeader, aData);
       
   519 	}
       
   520 
       
   521 EXPORT_C TInt RFileLogger::Handle() const
       
   522 	{
       
   523 	return iClogger.Handle();
       
   524 	}
       
   525 
       
   526 EXPORT_C TInt RFileLogger::Share() 
       
   527 	{
       
   528 	return iClogger.ShareAuto();
       
   529 	}
       
   530 
       
   531 EXPORT_C void RFileLogger::Write(const TDesC8& aSubsystem, const TDesC8& aComponent, const TDesC8& aText)
       
   532 	{
       
   533 	CheckConnected8(aSubsystem, aComponent);
       
   534 	clogger->Log(KEsc8, &aText);
       
   535 	}
       
   536 
       
   537 EXPORT_C void RFileLogger::Write(const TDesC8& aSubsystem, const TDesC8& aComponent, const TDesC& aText)
       
   538 	{
       
   539 	CheckConnected8(aSubsystem, aComponent);
       
   540 	clogger->Log(KEsc, &aText);
       
   541 	}
       
   542 
       
   543 EXPORT_C void RFileLogger::WriteFormat(const TDesC8& aSubsystem, const TDesC8& aComponent, TRefByValue<const TDesC16> aFmt, ...)
       
   544 	{
       
   545 	CheckConnected8(aSubsystem, aComponent);
       
   546 	VA_LIST args;
       
   547 	VA_START(args, aFmt);
       
   548 	clogger->LogList(aFmt, args);
       
   549 	VA_END(args);
       
   550 
       
   551 	STATICCLOSE();
       
   552 	}
       
   553 
       
   554 EXPORT_C void RFileLogger::WriteFormat(const TDesC8& aSubsystem, const TDesC8& aComponent, TRefByValue<const TDesC8> aFmt, ...)
       
   555 	{
       
   556 	CheckConnected8(aSubsystem, aComponent);
       
   557 	VA_LIST args;
       
   558 	VA_START(args, aFmt);
       
   559 	clogger->LogList(aFmt, args);
       
   560 	VA_END(args);
       
   561 
       
   562 	STATICCLOSE();
       
   563 	}
       
   564 
       
   565 EXPORT_C void RFileLogger::WriteFormat(const TDesC8& aSubsystem, const TDesC8& aComponent, const TRefByValue<const TDesC8> aFmt, VA_LIST& aList)
       
   566 	{
       
   567 	CheckConnected8(aSubsystem, aComponent);
       
   568 	clogger->LogList(aFmt, aList);
       
   569 
       
   570 	STATICCLOSE();
       
   571 	}
       
   572 
       
   573 EXPORT_C void RFileLogger::WriteFormat(const TDesC8& aSubsystem, const TDesC8& aComponent, const TRefByValue<const TDesC16> aFmt, VA_LIST& aList)
       
   574 	{
       
   575 	CheckConnected8(aSubsystem, aComponent);
       
   576 	clogger->LogList(aFmt, aList);
       
   577 
       
   578 	STATICCLOSE();
       
   579 	}
       
   580 
       
   581 #endif