First public contribution.
1 // Copyright (c) 1997-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".
8 // Initial Contributors:
9 // Nokia Corporation - initial contribution.
14 // Implements the Flogger client side
24 #include <comms-infras/commsdebugutility.h>
25 #include "comsdbgstd.h"
32 const TInt KHexDumpWidth=16; ///< Number of bytes written per line when formatting as hex.
33 const TInt KNumberMessageSlots=1; ///< Number of message slots on flogger client.no asynchronous IPC so never need more than 1 slot
34 const TInt KLowestPrintableCharacter = 32; ///< In Hex output, replace chars below space with a dot.
35 const TInt KHighestPrintableCharacter = 126; ///< In Hex output, replace chars above 7-bits with a dot.
37 _LIT(KFirstFormatString,"%s%04x : "); ///< Format string used in Hexdump to format first part: header and byte numbers.
38 _LIT(KSecondFormatString,"%02x "); ///< Format string used in Hexdump to format mid part: each of the 16 bytes as hex
39 _LIT(KThirdFormatString,"%c"); ///< Format string used in Hexdump to format the last part: each of the 16 bytes as characters
40 _LIT(KThreeSpaces," "); ///< Format string used in Hexdump to define padding between first and mid parts
41 _LIT(KTwoSpaces," "); ///< Format string used in Hexdump to define padding between hex and char bytes.
43 _LIT8(KFirstFormatString8,"%04x : "); ///< Format string used in Hexdump to format first part: header and byte numbers.
44 _LIT8(KSecondFormatString8,"%02x "); ///< Format string used in Hexdump to format mid part: each of the 16 bytes as hex
45 _LIT8(KThirdFormatString8,"%c"); ///< Format string used in Hexdump to format the last part: each of the 16 bytes as characters
46 _LIT8(KThreeSpaces8," "); ///< Format string used in Hexdump to define padding between first and mid parts
47 _LIT8(KTwoSpaces8," "); ///< Format string used in Hexdump to define padding between hex and char bytes.
52 // RFileLogger class definition
55 EXPORT_C RFileLogger::RFileLogger() : iLoggerBody(NULL)
57 * Create a new flogger client interface object with an empty body.
62 EXPORT_C RFileLogger::~RFileLogger()
69 EXPORT_C TVersion RFileLogger::Version() const
71 * Return the client side version number
73 * @return TVersion 3-part version number: major, minor, build.
77 return(TVersion(KFLogSrvMajorVersionNumber,KFLogSrvMinorVersionNumber,KFLogSrvBuildVersionNumber));
80 EXPORT_C TInt RFileLogger::Connect()
82 Connect to the flogger server - default number of message slots = 1
84 @return TInt indicating success code (KErrNone), KErrNoMemory if failed to allocate log body
85 or an error from RSessionBase::CreateSession.
86 KErrAlreadyExists if Connect has already been called.
91 return KErrAlreadyExists;
93 iLoggerBody = new RFileLoggerBody;
97 if (ret==KErrNotFound)
100 if (ret==KErrNone || ret==KErrAlreadyExists)
105 // we had a problem (perhaps no memory) so kill loggerbody again
114 //OOM, so return KErrNoMemory so that OOM tests know this
119 EXPORT_C void RFileLogger::Close()
121 * Close a client side session with the flogger server.
122 * @internalTechnology
123 * @post The client session is closed and the body of the class is deleted.
124 * Further calls to the Write functions will fail silently until a new session is opened.
129 iLoggerBody->Close();
135 EXPORT_C void RFileLogger::SetDateAndTime(TBool /*aUseDate*/,TBool /*aUseTime*/)
138 * @internalTechnology
139 * @removed This function no longer needed since now logging to one file and
140 * date/time comes from system.
144 EXPORT_C TInt RFileLogger::SetLogTags(const TDesC8& aSubsystem, const TDesC8& aComponent)
146 * Set the two tag strings that all further writes by this client will use to
147 * idenitfy it in the log file.
148 * @internalTechnology
149 * @param aSubsystem Specifies the tag1 name that goes into the log file
150 * @param aComponent specifies the tag2 name that goes into the log file
151 * @post The client session is updated so that all future calls use this tag set.
152 * Tags are truncated to KMaxTagLength.
153 * @return TInt indicating success code (KErrNone) or an error code.
154 * @note If an error occurs, the client connection will be silently closed to protect
158 TPtrC8 validSubsystem;
159 TPtrC8 validComponent;
161 validSubsystem.Set(aSubsystem.Left(KMaxTagLength));
162 validComponent.Set(aComponent.Left(KMaxTagLength));
163 return DoSetLogTags(validSubsystem, validComponent);
166 EXPORT_C void RFileLogger::CreateLog(const TDesC& aSubsystem, const TDesC& aComponent, TFileLoggingMode /*aMode*/)
169 * @internalTechnology
170 * @removed Not fully supported since flogger only uses one log file. Use SetLogTags instead.
171 * @param aSubsystem Specifies the tag1 name that goes into the log file
172 * @param aComponent specifies the tag2 name that goes into the log file
173 * @param aMode not used
174 * @note This function is partially supported and is equivalent to calling SetLogTags.
179 TNameTag narrowComponent;
180 CnvUtfConverter::ConvertFromUnicodeToUtf8(narrowComponent,aComponent);
181 TNameTag narrowSubsystem;
182 CnvUtfConverter::ConvertFromUnicodeToUtf8(narrowSubsystem,aSubsystem);
184 (void)DoSetLogTags(narrowSubsystem,narrowComponent);
187 EXPORT_C void RFileLogger::CloseLog()
189 * Close a client side session with the flogger server.
190 * @internalTechnology
191 * @deprecated With the advent of a single log file for all clients, closing the log file is no longer necessary. Use Close to close the session.
198 EXPORT_C TBool RFileLogger::LogValid() const
200 * Always returns ETrue.
201 * @internalTechnology
202 * @removed With the advent of a single log file for all clients, checking for log validity is no longer necessary.
203 * @return ETrue always.
209 EXPORT_C TInt RFileLogger::LastError() const
211 * Always returns KErrNone
212 * @internalTechnology
213 * @removed Flogger no longer retains internal errors.
214 * @return KErrNone always.
220 EXPORT_C TInt RFileLogger::ClearLog()
222 * Request that the server empty the log file.
223 * @internalTechnology
224 * @pre The client requesting the log be cleared must be listed in the flogger "ini" file
225 * as an enabled logging client. This prevents unwanted clients clearing the log.
226 * The session with the server must be active, otherwise this will fail silently.
227 * @post A message is added to the server write queue that indicates to clear the log.
228 * Once the message reaches the head of the queue flogger will empty the log file
229 * and begin filling it again.
230 * @return TInt indicating success code (KErrNone) or an error code.
235 __ASSERT_ALWAYS(iLoggerBody,User::Panic(KFloggerPanic, EInternalConsistencyFault));
236 return iLoggerBody->DoSendReceive(EClearLog, TIpcArgs());
245 // 16-bit non-static writes
248 EXPORT_C void RFileLogger::Write(const TDesC16& aText)
250 * Write 16-bit aText to the log file.
251 * @internalTechnology
252 * @pre The client requesting to log must be listed in the flogger "ini" file
253 * as an enabled logging client, otherwise no logging will occur.
254 * The session with the server must be active, otherwise this will fail silently.
255 * @param aText Text to write
256 * @post The 16-bit text is converted to 8-bit text before writing, and is truncated to KLogBufferSize
258 * The text is preceded in the log file by the two client tags and the client thread ID.
259 @note There is no need to supply CR, LF. If these are supplied it may cause the log output to be incorrect.
268 textValid.Set(aText.Left(KLogBufferSize));
269 TBuf8<KLogBufferSize> buf;
270 CnvUtfConverter::ConvertFromUnicodeToUtf8(buf,textValid);
274 EXPORT_C void RFileLogger::WriteFormat(TRefByValue<const TDesC16> aFmt,...)
276 * Write the formatted 16-bit string aFmt to the log file
277 * @internalTechnology
278 * @pre The client requesting to log must be listed in the flogger "ini" file
279 * as an enabled logging client, otherwise no logging will occur.
280 * The session with the server must be active, otherwise this will fail silently.
281 * @param aFmt c-style format descriptor, followed by any variables required by the format.
282 * @post The 16-bit text is converted to 8-bit text before writing, and is truncated to KLogBufferSize
284 * The text is preceded in the log file by the two client tags and the client thread ID.
294 //coverity[uninit_use_in_call]
295 DoWriteFormat(aFmt,list);
299 EXPORT_C void RFileLogger::WriteFormat(TRefByValue<const TDesC16> aFmt, VA_LIST& aList)
301 * Write the formatted 16-bit string aFmt to the log file.
302 * @internalTechnology
303 * @pre The client requesting to log must be listed in the flogger "ini" file
304 * as an enabled logging client, otherwise no logging will occur.
305 * The session with the server must be active, otherwise this will fail silently.
306 * @param aFmt c-style format descriptor
307 * @param aList any variables required by the format.
308 * @post The 16-bit text is converted to 8-bit text before writing, and is truncated to KLogBufferSize
310 * The text is preceded in the log file by the two client tags and the client thread ID.
315 DoWriteFormat(aFmt,aList);
320 // 8-bit non-static writes
323 EXPORT_C void RFileLogger::Write(const TDesC8& aText)
325 * Write 8-bit aText to the log file.
326 * @internalTechnology
327 * @pre The client requesting to log must be listed in the flogger "ini" file
328 * as an enabled logging client, otherwise no logging will occur.
329 * The session with the server must be active, otherwise this will fail silently.
330 * @param aText Text to log.
331 * @post The text is truncated to KLogBufferSize if necessary.
332 * The text is preceded in the log file by the two client tags and the client thread ID.
336 textValid.Set(aText.Left(KLogBufferSize));
343 EXPORT_C void RFileLogger::WriteFormat(TRefByValue<const TDesC8> aFmt,...)
345 * Write the formatted 8-bit string aFmt to the log file.
346 * @internalTechnology
347 * @pre The client requesting to log must be listed in the flogger "ini" file
348 * as an enabled logging client, otherwise no logging will occur.
349 * The session with the server must be active, otherwise this will fail silently.
350 * @param aFmt c-style format descriptor, followed by any variables required by the format.
351 * @post The text is truncated to KLogBufferSize if necessary.
352 * The text is preceded in the log file by the two client tags and the client thread ID.
362 //coverity[uninit_use_in_call]
363 DoWriteFormat(aFmt,list);
366 EXPORT_C void RFileLogger::WriteFormat(TRefByValue<const TDesC8> aFmt, VA_LIST& aList)
368 * Write the formatted 8-bit string aFmt to the log file if it is a valid file.
369 * @internalTechnology
370 * @pre The client requesting to log must be listed in the flogger "ini" file
371 * as an enabled logging client, otherwise no logging will occur.
372 * The session with the server must be active, otherwise this will fail silently.
373 * @param aFmt c-style format descriptor
374 * @param aList any variables required by the format.
375 * @post The text is truncated to KLogBufferSize if necessary.
376 * The text is preceded in the log file by the two client tags and the client thread ID.
381 DoWriteFormat(aFmt,aList);
385 EXPORT_C void RFileLogger::WriteBinary(const TDesC8& aData)
387 * Dump arbitrary data to the log file in a binary format.
388 * @internalTechnology
389 * @pre The client requesting to log must be listed in the flogger "ini" file
390 * as an enabled logging client, otherwise no logging will occur.
391 * The session with the server must be active, otherwise this will fail silently.
392 * @param aData Descriptor of the data to be dumped
393 * @post The 8-bit binary dump is preceded in the log file by the two client tags
395 * @note Unlike all other write API's, no thread ID is written with this API.
400 __ASSERT_ALWAYS(iLoggerBody,User::Panic(KFloggerPanic, EInternalConsistencyFault));
401 (void)iLoggerBody->DoSendReceive(EWriteBinary, TIpcArgs(&aData, aData.Length()));
407 // 16-bit static writes
410 EXPORT_C void RFileLogger::Write(const TDesC8& aSubsystem, const TDesC8& aComponent, const TDesC16& aText)
412 * Static write. Write 16-bit aText to the log file if it is a valid file.
413 * @internalTechnology
414 @pre The client requesting to log must be listed in the flogger "ini" file
415 as an enabled logging client, otherwise no logging will occur.
416 * @param aSubsystem Specifies the tag1 name that goes into the log file
417 * @param aComponent specifies the tag2 name that goes into the log file
418 * @param aMode not used
419 * @param aText Text to write
420 * @post The text is converted to 8-bit text before writing, and truncated to KLogBufferSize if necessary.
421 * The text is preceded in the log file by the two client tags and the client thread ID.
422 * "aSubsystem" and "aComponent" are each truncated to KMaxTagLength.
423 * @note This function has poor performance since it performs a full connection and disconnection to the flogger server.
427 TPtrC8 validSubsystem;
428 TPtrC8 validComponent;
430 validSubsystem.Set(aSubsystem.Left(KMaxTagLength));
431 validComponent.Set(aComponent.Left(KMaxTagLength));
433 TBuf8<KLogBufferSize> buf;
434 CnvUtfConverter::ConvertFromUnicodeToUtf8(buf,aText);
436 DoStaticWrite(validSubsystem, validComponent, buf);
439 EXPORT_C void RFileLogger::WriteFormat(const TDesC8& aSubsystem, const TDesC8& aComponent, const TRefByValue<const TDesC16> aFmt,...)
441 * Static write. Write the formatted 16-bit string aFmt to the log file.
442 * @internalTechnology
443 @pre The client requesting to log must be listed in the flogger "ini" file
444 as an enabled logging client, otherwise no logging will occur.
445 * @param aSubsystem Specifies the tag1 name that goes into the log file
446 * @param aComponent specifies the tag2 name that goes into the log file
447 * @param aFmt c-style format descriptor, followed by any variables required by the format.
448 * @post The text is converted to 8-bit text before writing, and truncated to KLogBufferSize if necessary.
449 * The text is preceded in the log file by the two client tags and the client thread ID.
450 * "aSubsystem" and "aComponent" are each truncated to KMaxTagLength.
451 * @note This function has poor performance since it performs a full connection and disconnection to the flogger server.
459 TPtrC8 validSubsystem;
460 TPtrC8 validComponent;
462 validSubsystem.Set(aSubsystem.Left(KMaxTagLength));
463 validComponent.Set(aComponent.Left(KMaxTagLength));
464 //coverity[uninit_use_in_call]
465 DoStaticWriteFormat(validSubsystem,validComponent,aFmt,list);
468 EXPORT_C void RFileLogger::WriteFormat(const TDesC8& aSubsystem, const TDesC8& aComponent, const TRefByValue<const TDesC16> aFmt, VA_LIST& aList)
470 * Static write. Write the formatted 16-bit string aFmt to the log file.
471 * @internalTechnology
472 @pre The client requesting to log must be listed in the flogger "ini" file
473 as an enabled logging client, otherwise no logging will occur.
474 * @param aSubsystem Specifies the tag1 name that goes into the log file
475 * @param aComponent specifies the tag2 name that goes into the log file
476 * @param aFmt c-style format descriptor
477 * @param aList any variables required by the format.
478 * @post The text is converted to 8-bit text before writing, and truncated to KLogBufferSize if necessary.
479 * The text is preceded in the log file by the two client tags and the client thread ID.
480 * "aSubsystem" and "aComponent" are each truncated to KMaxTagLength.
481 * @note This function has poor performance since it performs a full connection and disconnection to the flogger server.
485 TPtrC8 validSubsystem;
486 TPtrC8 validComponent;
488 validSubsystem.Set(aSubsystem.Left(KMaxTagLength));
489 validComponent.Set(aComponent.Left(KMaxTagLength));
491 DoStaticWriteFormat(validSubsystem,validComponent,aFmt,aList);
495 // 8-bit static writes
498 EXPORT_C void RFileLogger::Write(const TDesC8& aSubsystem, const TDesC8& aComponent, const TDesC8& aText)
500 * Static write. Write 8-bit aText to the log file.
501 * @internalTechnology
502 @pre The client requesting to log must be listed in the flogger "ini" file
503 as an enabled logging client, otherwise no logging will occur.
504 * @param aSubsystem Specifies the tag1 name that goes into the log file
505 * @param aComponent specifies the tag2 name that goes into the log file
506 * @param aText Text to log.
507 * @post The text is truncated to KLogBufferSize if necessary.
508 * The text is preceded in the log file by the two client tags and the client thread ID.
509 * "aSubsystem" and "aComponent" are each truncated to KMaxTagLength.
510 * @note This function has poor performance since it performs a full connection and disconnection to the flogger server.
514 TPtrC8 validSubsystem;
515 TPtrC8 validComponent;
517 validSubsystem.Set(aSubsystem.Left(KMaxTagLength));
518 validComponent.Set(aComponent.Left(KMaxTagLength));
519 DoStaticWrite(validSubsystem,validComponent, aText);
522 EXPORT_C void RFileLogger::WriteFormat(const TDesC8& aSubsystem, const TDesC8& aComponent, const TRefByValue<const TDesC8> aFmt,...)
524 * Static write. Write the formatted 8-bit string aFmt to the log file.
525 * @internalTechnology
526 @pre The client requesting to log must be listed in the flogger "ini" file
527 as an enabled logging client, otherwise no logging will occur.
528 * @param aSubsystem Specifies the tag1 name that goes into the log file
529 * @param aComponent specifies the tag2 name that goes into the log file
530 * @param aFmt c-style format descriptor, followed by any variables required by the format.
531 * @post The text is truncated to KLogBufferSize if necessary.
532 * The text is preceded in the log file by the two client tags and the client thread ID.
533 * "aSubsystem" and "aComponent" are each truncated to KMaxTagLength.
534 * @note This function has poor performance since it performs a full connection and disconnection to the flogger server.
543 TPtrC8 validSubsystem;
544 TPtrC8 validComponent;
546 validSubsystem.Set(aSubsystem.Left(KMaxTagLength));
547 validComponent.Set(aComponent.Left(KMaxTagLength));
548 //coverity[uninit_use_in_call]
549 DoStaticWriteFormat(validSubsystem,validComponent,aFmt,list);
552 EXPORT_C void RFileLogger::WriteFormat(const TDesC8& aSubsystem, const TDesC8& aComponent, const TRefByValue<const TDesC8> aFmt, VA_LIST& aList)
554 * Static write. Write the formatted 16-bit string aFmt to the log file.
555 * @internalTechnology
556 @pre The client requesting to log must be listed in the flogger "ini" file
557 as an enabled logging client, otherwise no logging will occur.
558 * @param aSubsystem Specifies the tag1 name that goes into the log file
559 * @param aComponent specifies the tag2 name that goes into the log file
560 * @param aFmt c-style format descriptor
561 * @param aList any variables required by the format.
562 * @post The text is truncated to KLogBufferSize if necessary.
563 * The text is preceded in the log file by the two client tags and the client thread ID.
564 * "aSubsystem" and "aComponent" are each truncated to KMaxTagLength.
565 * @note This function has poor performance since it performs a full connection and disconnection to the flogger server.
569 TPtrC8 validSubsystem;
570 TPtrC8 validComponent;
572 validSubsystem.Set(aSubsystem.Left(KMaxTagLength));
573 validComponent.Set(aComponent.Left(KMaxTagLength));
575 DoStaticWriteFormat(validSubsystem,validComponent,aFmt,aList);
584 // Removed 16-bit static writes
587 EXPORT_C void RFileLogger::Write(const TDesC& aSubsystem, const TDesC& aComponent, TFileLoggingMode /*aMode*/, const TDesC16& aText)
589 * Static write. Write 16-bit aText to the log file if it is a valid file.
590 * @internalTechnology
591 * @removed With the advent of a single log file for all clients, this function has been replaced by an equivalent without the aMode parameter.
592 @pre The client requesting to log must be listed in the flogger "ini" file
593 as an enabled logging client, otherwise no logging will occur.
594 * @param aSubsystem Specifies the tag1 name that goes into the log file
595 * @param aComponent specifies the tag2 name that goes into the log file
596 * @param aMode not used
597 * @param aText Text to write
598 * @post The text is converted to 8-bit text before writing, and truncated to KLogBufferSize if necessary.
599 * The text is preceded in the log file by the two client tags and the client thread ID.
600 * "aSubsystem" and "aComponent" are each truncated to KMaxTagLength.
601 * @note This function has poor performance since it performs a full connection and disconnection to the flogger server.
604 // the convert also truncates if necessary
605 TNameTag narrowComponent;
606 CnvUtfConverter::ConvertFromUnicodeToUtf8(narrowComponent,aComponent);
607 TNameTag narrowSubsystem;
608 CnvUtfConverter::ConvertFromUnicodeToUtf8(narrowSubsystem,aSubsystem);
610 Write(narrowSubsystem, narrowComponent, aText);
613 EXPORT_C void RFileLogger::WriteFormat(const TDesC& aSubsystem, const TDesC& aComponent, TFileLoggingMode aMode, TRefByValue<const TDesC16> aFmt,...)
615 * Static write. Write the formatted 16-bit string aFmt to the log file.
616 * @internalTechnology
617 * @removed With the advent of a single log file for all clients, this function has been replaced by an equivalent without the aMode parameter.
618 @pre The client requesting to log must be listed in the flogger "ini" file
619 as an enabled logging client, otherwise no logging will occur.
620 * @param aSubsystem Specifies the tag1 name that goes into the log file
621 * @param aComponent specifies the tag2 name that goes into the log file
622 * @param aMode not used
623 * @param aFmt c-style format descriptor, followed by any variables required by the format.
624 * @post The text is converted to 8-bit text before writing, and truncated to KLogBufferSize if necessary.
625 * The text is preceded in the log file by the two client tags and the client thread ID.
626 * "aSubsystem" and "aComponent" are each truncated to KMaxTagLength.
627 * @note This function has poor performance since it performs a full connection and disconnection to the flogger server.
630 // Just to remove the warning otherwise this does nothing
631 if (aMode == EFileLoggingModeUnknown) { }
636 // the convert also truncates if necessary
637 TNameTag narrowComponent;
638 CnvUtfConverter::ConvertFromUnicodeToUtf8(narrowComponent,aComponent);
639 TNameTag narrowSubsystem;
640 CnvUtfConverter::ConvertFromUnicodeToUtf8(narrowSubsystem,aSubsystem);
641 //coverity[uninit_use_in_call]
642 DoStaticWriteFormat(narrowSubsystem, narrowComponent,aFmt,list);
645 EXPORT_C void RFileLogger::WriteFormat(const TDesC& aSubsystem, const TDesC& aComponent, TFileLoggingMode /*aMode*/, TRefByValue<const TDesC16> aFmt, VA_LIST& aList)
647 * Static write. Write the formatted 16-bit string aFmt to the log file.
648 * @internalTechnology
649 * @removed With the advent of a single log file for all clients, this function has been replaced by an equivalent without the aMode parameter.
650 @pre The client requesting to log must be listed in the flogger "ini" file
651 as an enabled logging client, otherwise no logging will occur.
652 * @param aSubsystem Specifies the tag1 name that goes into the log file
653 * @param aComponent specifies the tag2 name that goes into the log file
654 * @param aMode not used
655 * @param aFmt c-style format descriptor
656 * @param aList any variables required by the format.
657 * @post The text is converted to 8-bit text before writing, and truncated to KLogBufferSize if necessary.
658 * The text is preceded in the log file by the two client tags and the client thread ID.
659 * "aSubsystem" and "aComponent" are each truncated to KMaxTagLength.
660 * @note This function has poor performance since it performs a full connection and disconnection to the flogger server.
663 // the convert also truncates if necessary
664 TNameTag narrowComponent;
665 CnvUtfConverter::ConvertFromUnicodeToUtf8(narrowComponent,aComponent);
666 TNameTag narrowSubsystem;
667 CnvUtfConverter::ConvertFromUnicodeToUtf8(narrowSubsystem,aSubsystem);
669 DoStaticWriteFormat(narrowSubsystem, narrowComponent,aFmt,aList);
673 // Removed 8-bit static writes
676 EXPORT_C void RFileLogger::Write(const TDesC& aSubsystem, const TDesC& aComponent, TFileLoggingMode /*aMode*/, const TDesC8& aText)
678 * Static write. Write 8-bit aText to the log file.
679 * @internalTechnology
680 * @removed With the advent of a single log file for all clients, this function has been replaced by an equivalent without the aMode parameter.
681 @pre The client requesting to log must be listed in the flogger "ini" file
682 as an enabled logging client, otherwise no logging will occur.
683 * @param aSubsystem Specifies the tag1 name that goes into the log file
684 * @param aComponent specifies the tag2 name that goes into the log file
685 * @param aMode not used
686 * @param aText Text to log.
687 * @post The text is truncated to KLogBufferSize if necessary.
688 * The text is preceded in the log file by the two client tags and the client thread ID.
689 * "aSubsystem" and "aComponent" are each truncated to KMaxTagLength.
690 * @note This function has poor performance since it performs a full connection and disconnection to the flogger server.
693 // the convert also truncates if necessary
694 TNameTag narrowComponent;
695 CnvUtfConverter::ConvertFromUnicodeToUtf8(narrowComponent,aComponent);
696 TNameTag narrowSubsystem;
697 CnvUtfConverter::ConvertFromUnicodeToUtf8(narrowSubsystem,aSubsystem);
699 Write(narrowSubsystem, narrowComponent, aText);
702 EXPORT_C void RFileLogger::WriteFormat(const TDesC& aSubsystem, const TDesC& aComponent, TFileLoggingMode aMode, TRefByValue<const TDesC8> aFmt,...)
704 * Static write. Write the formatted 8-bit string aFmt to the log file.
705 * @internalTechnology
706 * @removed With the advent of a single log file for all clients, this function has been replaced by an equivalent without the aMode parameter.
707 @pre The client requesting to log must be listed in the flogger "ini" file
708 as an enabled logging client, otherwise no logging will occur.
709 * @param aSubsystem Specifies the tag1 name that goes into the log file
710 * @param aComponent specifies the tag2 name that goes into the log file
711 * @param aMode not used
712 * @param aFmt c-style format descriptor, followed by any variables required by the format.
713 * @post The text is truncated to KLogBufferSize if necessary.
714 * The text is preceded in the log file by the two client tags and the client thread ID.
715 * "aSubsystem" and "aComponent" are each truncated to KMaxTagLength.
716 * @note This function has poor performance since it performs a full connection and disconnection to the flogger server.
720 // Just to remove the warning otherwise this does nothing
721 if (aMode == EFileLoggingModeUnknown) { }
726 // the convert also truncates if necessary
727 TNameTag narrowComponent;
728 CnvUtfConverter::ConvertFromUnicodeToUtf8(narrowComponent,aComponent);
729 TNameTag narrowSubsystem;
730 CnvUtfConverter::ConvertFromUnicodeToUtf8(narrowSubsystem,aSubsystem);
731 //coverity[uninit_use_in_call]
732 DoStaticWriteFormat(narrowSubsystem, narrowComponent, aFmt, list);
735 EXPORT_C void RFileLogger::WriteFormat(const TDesC& aSubsystem, const TDesC& aComponent, TFileLoggingMode /*aMode*/, TRefByValue<const TDesC8> aFmt, VA_LIST& aList)
737 * Static write. Write the formatted 16-bit string aFmt to the log file.
738 * @internalTechnology
739 * @removed With the advent of a single log file for all clients, this function has been replaced by an equivalent without the aMode parameter.
740 @pre The client requesting to log must be listed in the flogger "ini" file
741 as an enabled logging client, otherwise no logging will occur.
742 * @param aSubsystem Specifies the tag1 name that goes into the log file
743 * @param aComponent specifies the tag2 name that goes into the log file
744 * @param aMode not used
745 * @param aFmt c-style format descriptor
746 * @param aList any variables required by the format.
747 * @post The text is truncated to KLogBufferSize if necessary.
748 * The text is preceded in the log file by the two client tags and the client thread ID.
749 * "aSubsystem" and "aComponent" are each truncated to KMaxTagLength.
750 * @note This function has poor performance since it performs a full connection and disconnection to the flogger server.
753 // the convert also truncates if necessary
754 TNameTag narrowComponent;
755 CnvUtfConverter::ConvertFromUnicodeToUtf8(narrowComponent,aComponent);
756 TNameTag narrowSubsystem;
757 CnvUtfConverter::ConvertFromUnicodeToUtf8(narrowSubsystem,aSubsystem);
759 DoStaticWriteFormat(narrowSubsystem, narrowComponent,aFmt,aList);
766 EXPORT_C void RFileLogger::HexDump(const TText* aHeader, const TText* aMargin, const TUint8* aPtr, TInt aLen)
768 * Dump arbitrary data to the log file as a standard hex dump.
769 * @internalTechnology
770 * @pre The session with the server must be active, otherwise this no action is taken.
771 The client requesting to log must be listed in the flogger "ini" file
772 as an enabled logging client, otherwise no logging will occur.
773 * @param aHeader Specify a zero-terminated string to be printed before the first hex line. Leave as null or an empty string for no header.
774 * @param aMargin Specify a zero-terminated string to be printed before each subsequent line. Leave as null or an empty string for no Margin.
775 * @param aPtr pointer to the data being dumped.
776 * @param aLen the number of bytes to dump
777 * @post Each line is preceded in the log file by the two client tags and the client thread ID.
778 * @note Example of aHeader/aMargin. If "aHeader" is set to "Fn Output:" and "aMargin" is set to " ", then output would look
779 * like (for a print of the alphabet):
780 * TLOG Example 20 FnOutput:0000 : 61 62 63 64 65 66 67 68 69 6a 6b 6c 6d 6e 6f 70 abcdefghijklmnop
781 * TLOG Example 20 0010 : 71 72 73 74 75 76 77 78 79 7a qrstuvwxyz
787 DoHexDump(aHeader,aMargin,aPtr,aLen);
795 EXPORT_C void RFileLogger::HexDump(const TDesC8& aData, const TDesC8& aHeader)
797 * Dump arbitrary data to the log file as a standard hex dump.
798 * @internalTechnology
799 * @pre The session with the server must be active, otherwise this no action is taken.
800 The client requesting to log must be listed in the flogger "ini" file
801 as an enabled logging client, otherwise no logging will occur.
802 * @param aData the data being dumped.
803 * @param aHeader Specify a string to be printed before the first hex line. If not supplied, no header or margin is written.
804 * If supplied, then subsequent lines are indented to the length of aHeader.
805 * @post Each line is preceded in the log file by the two client tags and the client thread ID.
806 * @note Example of aHeader. If "aHeader" is set to "Fn Output:" then output would look
807 * like (for a print of the alphabet):
808 * TLOG Example 20 FnOutput:0000 : 61 62 63 64 65 66 67 68 69 6a 6b 6c 6d 6e 6f 70 abcdefghijklmnop
809 * TLOG Example 20 0010 : 71 72 73 74 75 76 77 78 79 7a qrstuvwxyz
815 DoHexDump(aData,aHeader,TPtrC8(NULL,0));
826 EXPORT_C void RFileLogger::HexDump(const TDesC8& aSubsystem, const TDesC8& aComponent, const TDesC8& aData, const TDesC8& aHeader)
828 * Static Write. Dump arbitrary data to the log file as a standard hex dump.
829 * @internalTechnology
830 @pre The client requesting to log must be listed in the flogger "ini" file
831 as an enabled logging client, otherwise no logging will occur.
832 * @param aSubsystem Specifies the tag1 name that goes into the log file
833 * @param aComponent specifies the tag2 name that goes into the log file
834 * @param aData the data being dumped.
835 * @param aHeader Specify a string to be printed before the first hex line. If not supplied, no header or Margin is written.
836 * @param aMargin Specify a string to be printed before each subsequent line. If not supplied, a string of spaces equal to the length of aHeader is used.
837 * @post Each line is preceded in the log file by the two client tags and the client thread ID.
838 * "aSubsystem" and "aComponent" are each truncated to KMaxTagLength.
839 * @note This function has poor performance since it performs a full connection and disconnection to the flogger server.
840 * Example of aHeader/aMargin. If "aHeader" is set to "Fn Output:" and "aMargin" is set to " ", then output would look
841 * like (for a print of the alphabet):
842 * TLOG Example 20 FnOutput:0000 : 61 62 63 64 65 66 67 68 69 6a 6b 6c 6d 6e 6f 70 abcdefghijklmnop
843 * TLOG Example 20 0010 : 71 72 73 74 75 76 77 78 79 7a qrstuvwxyz
848 TInt ret=logger.Connect();
851 ret = logger.SetLogTags(aSubsystem,aComponent);
852 if (((ret == KErrNone) && logger.iLoggerBody) && logger.iLoggerBody->iLoggingOnPckg())
854 logger.DoHexDump(aData,aHeader,TPtrC8(NULL,0));
864 EXPORT_C void RFileLogger::HexDump(const TDesC& aSubsystem, const TDesC& aComponent, TFileLoggingMode /*aMode*/, const TText* aHeader, const TText* aMargin, const TUint8* aPtr, TInt aLen)
866 * Static Write. Dump arbitrary data to the log file as a standard hex dump.
867 * @internalTechnology
868 * @removed With the advent of a single log file for all clients, this function has been replaced by an equivalent without the aMode parameter.
869 @pre The client requesting to log must be listed in the flogger "ini" file
870 as an enabled logging client, otherwise no logging will occur.
871 * @param aSubsystem Specifies the tag1 name that goes into the log file
872 * @param aComponent specifies the tag2 name that goes into the log file
873 * @param aMode not used
874 * @param aHeader Specify a zero-terminated string to be printed before the first hex line. Leave as null or an empty string for no header.
875 * @param aMargin Specify a zero-terminated string to be printed before each subsequent line. Leave as null or an empty string for no Margin.
876 * @param aPtr pointer to the data being dumped.
877 * @param aLen the number of bytes to dump
878 * @post Each line is preceded in the log file by the two client tags and the client thread ID.
879 * "aSubsystem" and "aComponent" are each truncated to KMaxTagLength.
880 * @note This function has poor performance since it performs a full connection and disconnection to the flogger server.
881 * Example of aHeader/aMargin. If "aHeader" is set to "Fn Output:" and "aMargin" is set to " ", then output would look
882 * like (for a print of the alphabet):
883 * TLOG Example 20 FnOutput:0000 : 61 62 63 64 65 66 67 68 69 6a 6b 6c 6d 6e 6f 70 abcdefghijklmnop
884 * TLOG Example 20 0010 : 71 72 73 74 75 76 77 78 79 7a qrstuvwxyz
888 // the convert also truncates if necessary
889 TNameTag narrowComponent;
890 CnvUtfConverter::ConvertFromUnicodeToUtf8(narrowComponent,aComponent);
891 TNameTag narrowSubsystem;
892 CnvUtfConverter::ConvertFromUnicodeToUtf8(narrowSubsystem,aSubsystem);
895 TInt ret=logger.Connect();
898 ret = logger.SetLogTags(narrowSubsystem,narrowComponent);
899 if (((ret == KErrNone) && logger.iLoggerBody) && logger.iLoggerBody->iLoggingOnPckg())
901 logger.DoHexDump(aHeader,aMargin,aPtr,aLen);
909 EXPORT_C TInt RFileLogger::Handle() const
910 // Returns handle of session, or Null if no session.
914 return iLoggerBody->Handle();
922 EXPORT_C TInt RFileLogger::Share()
926 return iLoggerBody->ShareAuto();
928 return KErrSessionClosed;
933 // Debug tools to check for memory leaks
936 EXPORT_C void RFileLogger::__DbgShutDownServer()
938 * Debugging Tool. Ask the flogger server to shutdown. Only valid in DEBUG builds.
939 * @internalTechnology
944 (void)iLoggerBody->DoSendReceive(EShutDownServer);
948 EXPORT_C void RFileLogger::__DbgSetHeapFailure(TInt aFailAfter)
950 * Debugging Tool. Ask the flogger server to set its heap failure. Only valid in DEBUG builds.
951 * @internalTechnology
952 * @param aFailAfter The number of successful memory allocations which will occur before
953 * a memory allocation is failed by the memory manager.
959 (void)iLoggerBody->DoSendReceive(ESetHeapFailure, TIpcArgs(aFailAfter));
970 TInt RFileLogger::DoConnect()
972 * Connect to the flogger server
973 * @return TInt indicating success code (KErrNone) or an error code.
974 * @note: creates 1 slot: no asynchronous IPC so never need more than 1 reserved message slot.
978 __ASSERT_ALWAYS(iLoggerBody,User::Panic(KFloggerPanic, EInternalConsistencyFault));
979 return iLoggerBody->DoCreateSession(KFLoggerServerName,Version(),KNumberMessageSlots);
982 TInt RFileLogger::DoSetLogTags(const TDesC8& aSubsystem, const TDesC8& aComponent)
984 * Set the two tag strings that all further writes by this client will use to
985 * identify it in the log file.
986 * @param aSubsystem Specifies the tag1 name that goes into the log file
987 * @param aComponent specifies the tag2 name that goes into the log file
988 * @return TInt indicating success code (KErrNone), or (KErrNotFound) if
989 the connection is not valid, or an error code from SendReceive.
990 * @note If an error occurs, the client connection will be silently closed to protect
995 if (iLoggerBody) //check that the connection was set up correctly
997 err = iLoggerBody->DoSendReceive(ESetLogTag, TIpcArgs(&aSubsystem, &aComponent, &(iLoggerBody->iLoggingOnPckg)));
999 { //Something went wrong. We need to protect the client because error can be ignored.
1010 void RFileLogger::DoWrite(const TDesC8& aBuf)
1012 * Send to the flogger server the pre-formatted write string.
1013 * @internalTechnology
1014 * @pre session is already open.
1015 * @param aBuf 8-bit text to be written. It must not exceed KLogBufferSize.
1018 __ASSERT_ALWAYS(iLoggerBody,User::Panic(KFloggerPanic, EInternalConsistencyFault));
1019 (void)iLoggerBody->DoSendReceive(EWriteToLog,TIpcArgs(&aBuf, aBuf.Length()));
1022 void RFileLogger::DoWriteFormat(TRefByValue<const TDesC16> aFmt, VA_LIST& aList)
1024 * Trim and convert format string before sending to the flogger server.
1025 * @pre session is already open.
1026 * @param aFmt c-style formatted text to be written.
1027 * @param aList any variables required by the format.
1028 * @post The final string is truncated to KLogBufferSize and converted to 8-bit.
1031 TBuf16<KLogBufferSize> wideBuf;
1032 __ASSERT_ALWAYS(iLoggerBody,User::Panic(KFloggerPanic, EInternalConsistencyFault));
1033 wideBuf.AppendFormatList(aFmt, aList, &(iLoggerBody->iFlogOverflow16));
1034 TBuf8<KLogBufferSize> narrowBuf;
1035 CnvUtfConverter::ConvertFromUnicodeToUtf8(narrowBuf,wideBuf);
1039 void RFileLogger::DoWriteFormat(TRefByValue<const TDesC8> aFmt, VA_LIST& aList)
1041 * Trim format string before sending to the flogger server.
1042 * @pre session is already open.
1043 * @param aFmt c-style formatted text to be written.
1044 * @param aList any variables required by the format.
1045 * @post The final string is truncated to KLogBufferSize.
1048 TBuf8<KLogBufferSize> buf;
1049 __ASSERT_ALWAYS(iLoggerBody,User::Panic(KFloggerPanic, EInternalConsistencyFault));
1050 buf.AppendFormatList(aFmt,aList, &(iLoggerBody->iFlogOverflow8));
1054 void RFileLogger::DoSendStaticWrite(const TDesC8& aSubsystem, const TDesC8& aComponent, const TDesC8& aText)
1056 * Send to the flogger server the pre-formatted write string.
1057 * @pre session is already open.
1058 * aText is not longer than KLogBufferSize
1059 * @param aSubsystem Specifies the tag1 name that goes into the log file
1060 * @param aComponent specifies the tag2 name that goes into the log file
1061 * @param aText text to write
1062 * @post The text is only written if the tag1+tag2 combination is listed as an enabled client
1063 * in the flogger "ini" file, otherwise no action is taken.
1064 * The text is preceded in the log file by the two client tags and the client thread ID.
1067 __ASSERT_ALWAYS(iLoggerBody,User::Panic(KFloggerPanic, EInternalConsistencyFault));
1068 (void)iLoggerBody->DoSendReceive(EStaticWriteToLog,TIpcArgs(&aSubsystem, &aComponent, &aText, aText.Length())); // ignore error
1071 void RFileLogger::DoStaticWrite(const TDesC8& aSubsystem, const TDesC8& aComponent, const TDesC8& aText)
1073 * Send to the flogger server the pre-formatted write string.
1074 * @pre session is already open.
1075 * aText is not longer than KLogBufferSize
1076 * @param aSubsystem Specifies the tag1 name that goes into the log file
1077 * @param aComponent specifies the tag2 name that goes into the log file
1078 * @param aText text to write
1079 * @post The text is only written if the tag1+tag2 combination is listed as an enabled client
1080 * in the flogger "ini" file, otherwise no action is taken.
1081 * The text is preceded in the log file by the two client tags and the client thread ID.
1085 TInt ret=logger.Connect();
1089 textValid.Set(aText.Left(KLogBufferSize));
1091 logger.DoSendStaticWrite(aSubsystem, aComponent, textValid);
1099 void RFileLogger::DoStaticWriteFormat(const TDesC8& aSubsystem, const TDesC8& aComponent, TRefByValue<const TDesC> aFmt, VA_LIST& aList)
1101 * Send to the flogger server a format write string.
1102 * @param aSubsystem Specifies the tag1 name that goes into the log file
1103 * @param aComponent specifies the tag2 name that goes into the log file
1104 * @param aFmt c-style formatted text to be written.
1105 * @param aList any variables required by the format.
1106 * @post The text is only written if the tag1+tag2 combination is listed as an enabled client
1107 * in the flogger "ini" file, otherwise no action is taken.
1108 * If necessary, the final string is truncated to KLogBufferSize.
1109 * The final string is converted to an 8-bit string.
1110 * The text is preceded in the log file by the two client tags and the client thread ID.
1113 TFlogOverflow16 objFlogBody16;
1114 TBuf<KLogBufferSize> wideBuf;
1115 TBuf8<KLogBufferSize> narrowBuf;
1117 wideBuf.AppendFormatList(aFmt, aList, &objFlogBody16);
1118 CnvUtfConverter::ConvertFromUnicodeToUtf8(narrowBuf,wideBuf);
1120 DoStaticWrite(aSubsystem, aComponent, narrowBuf);
1123 void RFileLogger::DoStaticWriteFormat(const TDesC8& aSubsystem, const TDesC8& aComponent, TRefByValue<const TDesC8> aFmt, VA_LIST& aList)
1125 * Send to the flogger server a format write string.
1126 * @param aSubsystem Specifies the tag1 name that goes into the log file
1127 * @param aComponent specifies the tag2 name that goes into the log file
1128 * @param aFmt c-style formatted text to be written.
1129 * @param aList any variables required by the format.
1130 * @post The text is only written if the tag1+tag2 combination is listed as an enabled client
1131 * in the flogger "ini" file, otherwise no action is taken.
1132 * If necessary, the final string is truncated to KLogBufferSize.
1133 * The text is preceded in the log file by the two client tags and the client thread ID.
1135 TFlogOverflow8 objFlogBody8;
1136 TBuf8<KLogBufferSize> buf;
1137 buf.AppendFormatList(aFmt, aList, &objFlogBody8);
1139 DoStaticWrite(aSubsystem, aComponent, buf);
1142 void RFileLogger::DoHexDump(const TText* aHeader, const TText* aMargin, const TUint8* aPtr, TInt aLen)
1144 * Static Write. Dump arbitrary data to the log file as a standard hex dump.
1145 * @pre session is already open.
1146 * @param aHeader Specify a zero-terminated string to be printed before the first hex line. Leave as null or an empty string for no header.
1147 * @param aMargin Specify a zero-terminated string to be printed before each subsequent line. Leave as null or an empty string for no Margin.
1148 * @param aPtr pointer to the data being dumped.
1149 * @param aLen the number of bytes to dump
1150 * @post The text is only written if the tag1+tag2 combination is listed as an enabled client
1151 * in the flogger "ini" file, otherwise no action is taken.
1152 * Each line is preceded in the log file by the two client tags and the client thread ID.
1153 * The data is written in lines of 16 characters.
1154 * @note Example of aHeader/aMargin. If "aHeader" is set to "Fn Output:" and "aMargin" is set to " ", then output would look
1155 * like (for a print of the alphabet):
1156 * TLOG Example 20 FnOutput:0000 : 61 62 63 64 65 66 67 68 69 6a 6b 6c 6d 6e 6f 70 abcdefghijklmnop
1157 * TLOG Example 20 0010 : 71 72 73 74 75 76 77 78 79 7a qrstuvwxyz
1161 // this delightful art-deco code lifted straight from old flogger
1162 if (aPtr==NULL) // nothing to do
1167 TBuf<KMaxHexDumpWidth> buf;
1168 TBuf8<KMaxHexDumpWidth> temp;
1172 const TText* p=aHeader;
1177 p=BLANK; // if NULL set p to a blank string
1179 TInt n=(aLen>KHexDumpWidth ? KHexDumpWidth : aLen);
1180 __ASSERT_ALWAYS(iLoggerBody,User::Panic(KFloggerPanic, EInternalConsistencyFault));
1181 buf.AppendFormat(KFirstFormatString,&(iLoggerBody->iFlogOverflow16),p,i);
1185 buf.AppendFormat(KSecondFormatString,aPtr[i+j]);
1187 while (j++<KHexDumpWidth)
1189 buf.Append(KThreeSpaces);
1191 buf.Append(KTwoSpaces);
1194 buf.AppendFormat(KThirdFormatString,(aPtr[i+j]<KLowestPrintableCharacter || aPtr[i+j]>KHighestPrintableCharacter) ? KFullStopChar : aPtr[i+j]);
1197 CnvUtfConverter::ConvertFromUnicodeToUtf8(temp,buf);
1210 void RFileLogger::DoHexDump(const TDesC8& aData, const TDesC8& aHeader, const TDesC8& aMargin)
1212 * Static Write. Dump arbitrary data to the log file as a standard hex dump.
1213 * @see RFileLogger::HexDump(const TDesC8& aData, const TDesC8& aHeader = 0)
1214 * @param aMargin - supply a margin - if left null, then a margin of spaces of equal length to "aHeader"
1216 * @pre session is already open.
1219 HBufC8* marginStr = NULL;
1220 TBuf8<KMaxHexDumpWidth> buf;
1221 TInt aRemainingLen = aData.Length();
1222 TInt aHeaderLen = aHeader.Length();
1224 __ASSERT_ALWAYS(iLoggerBody,User::Panic(KFloggerPanic, EInternalConsistencyFault));
1226 if (aData.Length()==0) // nothing to do
1235 if (aMargin.Length() == 0)
1237 marginStr = HBufC8::New(aHeader.Length());
1238 if (marginStr == NULL)
1240 return; // abort if No memory
1242 TPtr8 marginStrPtr(marginStr->Des());
1243 marginStrPtr.AppendFill(' ',aHeader.Length());
1247 marginStr = aMargin.Alloc();
1253 TUint blockStartPos = 0;
1254 while (aRemainingLen>0)
1256 TInt blockLength = (aRemainingLen>KHexDumpWidth ? KHexDumpWidth : aRemainingLen);
1258 // write the header/margin and print in hex which bytes we are about to write
1259 if (blockStartPos == 0)
1263 buf.Append(aHeader);
1265 buf.AppendFormat(KFirstFormatString8,&(iLoggerBody->iFlogOverflow8), blockStartPos);
1271 buf.Append(*marginStr);
1273 buf.AppendFormat(KFirstFormatString8,&(iLoggerBody->iFlogOverflow8),blockStartPos);
1277 // write the bytes as hex
1278 for (bytePos = 0; bytePos < blockLength; bytePos++)
1280 buf.AppendFormat(KSecondFormatString8,aData[blockStartPos + bytePos]);
1282 while (bytePos++ < KHexDumpWidth)
1284 buf.Append(KThreeSpaces8);
1286 buf.Append(KTwoSpaces8);
1287 // print the bytes as characters, or full stops if outside printable range
1288 for (bytePos = 0; bytePos < blockLength; bytePos++)
1290 buf.AppendFormat(KThirdFormatString8,(aData[blockStartPos + bytePos] < KLowestPrintableCharacter || aData[blockStartPos + bytePos] > KHighestPrintableCharacter) ? KFullStopChar8 : aData[blockStartPos + bytePos]);
1296 aRemainingLen -= blockLength;
1297 blockStartPos += blockLength;
1304 EXPORT_C void ClientRunStubOrdinal1()
1306 * @removed This function has been removed because the flogsvrl dll contains the equivalent function
1309 {User::Panic(KFloggerPanic, KErrNotSupported);}