sl@0: // Copyright (c) 1997-2009 Nokia Corporation and/or its subsidiary(-ies). sl@0: // All rights reserved. sl@0: // This component and the accompanying materials are made available sl@0: // under the terms of "Eclipse Public License v1.0" sl@0: // which accompanies this distribution, and is available sl@0: // at the URL "http://www.eclipse.org/legal/epl-v10.html". sl@0: // sl@0: // Initial Contributors: sl@0: // Nokia Corporation - initial contribution. sl@0: // sl@0: // Contributors: sl@0: // sl@0: // Description: sl@0: // Implements the Flogger client side sl@0: // sl@0: // sl@0: sl@0: /** sl@0: @file sl@0: @internalTechnology sl@0: */ sl@0: sl@0: #include sl@0: #include sl@0: #include "comsdbgstd.h" sl@0: #include sl@0: sl@0: #include sl@0: sl@0: #define BLANK _S("") sl@0: sl@0: const TInt KHexDumpWidth=16; ///< Number of bytes written per line when formatting as hex. sl@0: const TInt KNumberMessageSlots=1; ///< Number of message slots on flogger client.no asynchronous IPC so never need more than 1 slot sl@0: const TInt KLowestPrintableCharacter = 32; ///< In Hex output, replace chars below space with a dot. sl@0: const TInt KHighestPrintableCharacter = 126; ///< In Hex output, replace chars above 7-bits with a dot. sl@0: sl@0: _LIT(KFirstFormatString,"%s%04x : "); ///< Format string used in Hexdump to format first part: header and byte numbers. sl@0: _LIT(KSecondFormatString,"%02x "); ///< Format string used in Hexdump to format mid part: each of the 16 bytes as hex sl@0: _LIT(KThirdFormatString,"%c"); ///< Format string used in Hexdump to format the last part: each of the 16 bytes as characters sl@0: _LIT(KThreeSpaces," "); ///< Format string used in Hexdump to define padding between first and mid parts sl@0: _LIT(KTwoSpaces," "); ///< Format string used in Hexdump to define padding between hex and char bytes. sl@0: sl@0: _LIT8(KFirstFormatString8,"%04x : "); ///< Format string used in Hexdump to format first part: header and byte numbers. sl@0: _LIT8(KSecondFormatString8,"%02x "); ///< Format string used in Hexdump to format mid part: each of the 16 bytes as hex sl@0: _LIT8(KThirdFormatString8,"%c"); ///< Format string used in Hexdump to format the last part: each of the 16 bytes as characters sl@0: _LIT8(KThreeSpaces8," "); ///< Format string used in Hexdump to define padding between first and mid parts sl@0: _LIT8(KTwoSpaces8," "); ///< Format string used in Hexdump to define padding between hex and char bytes. sl@0: sl@0: sl@0: sl@0: // sl@0: // RFileLogger class definition sl@0: // sl@0: sl@0: EXPORT_C RFileLogger::RFileLogger() : iLoggerBody(NULL) sl@0: /** sl@0: * Create a new flogger client interface object with an empty body. sl@0: * @internalTechnology sl@0: */ sl@0: {} sl@0: sl@0: EXPORT_C RFileLogger::~RFileLogger() sl@0: /** sl@0: * Destructor sl@0: * @internalTechnology sl@0: */ sl@0: {} sl@0: sl@0: EXPORT_C TVersion RFileLogger::Version() const sl@0: /** sl@0: * Return the client side version number sl@0: * @internalTechnology sl@0: * @return TVersion 3-part version number: major, minor, build. sl@0: */ sl@0: { sl@0: sl@0: return(TVersion(KFLogSrvMajorVersionNumber,KFLogSrvMinorVersionNumber,KFLogSrvBuildVersionNumber)); sl@0: } sl@0: sl@0: EXPORT_C TInt RFileLogger::Connect() sl@0: /** sl@0: Connect to the flogger server - default number of message slots = 1 sl@0: @internalTechnology sl@0: @return TInt indicating success code (KErrNone), KErrNoMemory if failed to allocate log body sl@0: or an error from RSessionBase::CreateSession. sl@0: KErrAlreadyExists if Connect has already been called. sl@0: */ sl@0: { sl@0: if (iLoggerBody) sl@0: { sl@0: return KErrAlreadyExists; sl@0: } sl@0: iLoggerBody = new RFileLoggerBody; sl@0: if (iLoggerBody) sl@0: { sl@0: TInt ret=DoConnect(); sl@0: if (ret==KErrNotFound) sl@0: { sl@0: ret=FLogger::Start(); sl@0: if (ret==KErrNone || ret==KErrAlreadyExists) sl@0: ret=DoConnect(); sl@0: } sl@0: if (ret != KErrNone) sl@0: { sl@0: // we had a problem (perhaps no memory) so kill loggerbody again sl@0: delete iLoggerBody; sl@0: iLoggerBody = NULL; sl@0: } sl@0: sl@0: return ret; sl@0: } sl@0: else sl@0: { sl@0: //OOM, so return KErrNoMemory so that OOM tests know this sl@0: return KErrNoMemory; sl@0: } sl@0: } sl@0: sl@0: EXPORT_C void RFileLogger::Close() sl@0: /** sl@0: * Close a client side session with the flogger server. sl@0: * @internalTechnology sl@0: * @post The client session is closed and the body of the class is deleted. sl@0: * Further calls to the Write functions will fail silently until a new session is opened. sl@0: */ sl@0: { sl@0: if (iLoggerBody) sl@0: { sl@0: iLoggerBody->Close(); sl@0: delete iLoggerBody; sl@0: } sl@0: iLoggerBody = NULL; sl@0: } sl@0: sl@0: EXPORT_C void RFileLogger::SetDateAndTime(TBool /*aUseDate*/,TBool /*aUseTime*/) sl@0: /** sl@0: * Does nothing. sl@0: * @internalTechnology sl@0: * @removed This function no longer needed since now logging to one file and sl@0: * date/time comes from system. sl@0: */ sl@0: {} sl@0: sl@0: EXPORT_C TInt RFileLogger::SetLogTags(const TDesC8& aSubsystem, const TDesC8& aComponent) sl@0: /** sl@0: * Set the two tag strings that all further writes by this client will use to sl@0: * idenitfy it in the log file. sl@0: * @internalTechnology sl@0: * @param aSubsystem Specifies the tag1 name that goes into the log file sl@0: * @param aComponent specifies the tag2 name that goes into the log file sl@0: * @post The client session is updated so that all future calls use this tag set. sl@0: * Tags are truncated to KMaxTagLength. sl@0: * @return TInt indicating success code (KErrNone) or an error code. sl@0: * @note If an error occurs, the client connection will be silently closed to protect sl@0: * the client. sl@0: */ sl@0: { sl@0: TPtrC8 validSubsystem; sl@0: TPtrC8 validComponent; sl@0: sl@0: validSubsystem.Set(aSubsystem.Left(KMaxTagLength)); sl@0: validComponent.Set(aComponent.Left(KMaxTagLength)); sl@0: return DoSetLogTags(validSubsystem, validComponent); sl@0: } sl@0: sl@0: EXPORT_C void RFileLogger::CreateLog(const TDesC& aSubsystem, const TDesC& aComponent, TFileLoggingMode /*aMode*/) sl@0: /** sl@0: * Sets the log tags. sl@0: * @internalTechnology sl@0: * @removed Not fully supported since flogger only uses one log file. Use SetLogTags instead. sl@0: * @param aSubsystem Specifies the tag1 name that goes into the log file sl@0: * @param aComponent specifies the tag2 name that goes into the log file sl@0: * @param aMode not used sl@0: * @note This function is partially supported and is equivalent to calling SetLogTags. sl@0: * @see SetLogTags sl@0: */ sl@0: { sl@0: sl@0: TNameTag narrowComponent; sl@0: CnvUtfConverter::ConvertFromUnicodeToUtf8(narrowComponent,aComponent); sl@0: TNameTag narrowSubsystem; sl@0: CnvUtfConverter::ConvertFromUnicodeToUtf8(narrowSubsystem,aSubsystem); sl@0: sl@0: (void)DoSetLogTags(narrowSubsystem,narrowComponent); sl@0: } sl@0: sl@0: EXPORT_C void RFileLogger::CloseLog() sl@0: /** sl@0: * Close a client side session with the flogger server. sl@0: * @internalTechnology sl@0: * @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. sl@0: * @see Close sl@0: */ sl@0: { sl@0: Close(); sl@0: } sl@0: sl@0: EXPORT_C TBool RFileLogger::LogValid() const sl@0: /** sl@0: * Always returns ETrue. sl@0: * @internalTechnology sl@0: * @removed With the advent of a single log file for all clients, checking for log validity is no longer necessary. sl@0: * @return ETrue always. sl@0: */ sl@0: { sl@0: return ETrue; sl@0: } sl@0: sl@0: EXPORT_C TInt RFileLogger::LastError() const sl@0: /** sl@0: * Always returns KErrNone sl@0: * @internalTechnology sl@0: * @removed Flogger no longer retains internal errors. sl@0: * @return KErrNone always. sl@0: */ sl@0: { sl@0: return KErrNone; sl@0: } sl@0: sl@0: EXPORT_C TInt RFileLogger::ClearLog() sl@0: /** sl@0: * Request that the server empty the log file. sl@0: * @internalTechnology sl@0: * @pre The client requesting the log be cleared must be listed in the flogger "ini" file sl@0: * as an enabled logging client. This prevents unwanted clients clearing the log. sl@0: * The session with the server must be active, otherwise this will fail silently. sl@0: * @post A message is added to the server write queue that indicates to clear the log. sl@0: * Once the message reaches the head of the queue flogger will empty the log file sl@0: * and begin filling it again. sl@0: * @return TInt indicating success code (KErrNone) or an error code. sl@0: */ sl@0: { sl@0: if (IsLogging()) sl@0: { sl@0: __ASSERT_ALWAYS(iLoggerBody,User::Panic(KFloggerPanic, EInternalConsistencyFault)); sl@0: return iLoggerBody->DoSendReceive(EClearLog, TIpcArgs()); sl@0: } sl@0: else sl@0: { sl@0: return KErrNone; sl@0: } sl@0: } sl@0: sl@0: // sl@0: // 16-bit non-static writes sl@0: // sl@0: sl@0: EXPORT_C void RFileLogger::Write(const TDesC16& aText) sl@0: /** sl@0: * Write 16-bit aText to the log file. sl@0: * @internalTechnology sl@0: * @pre The client requesting to log must be listed in the flogger "ini" file sl@0: * as an enabled logging client, otherwise no logging will occur. sl@0: * The session with the server must be active, otherwise this will fail silently. sl@0: * @param aText Text to write sl@0: * @post The 16-bit text is converted to 8-bit text before writing, and is truncated to KLogBufferSize sl@0: * if necessary. sl@0: * The text is preceded in the log file by the two client tags and the client thread ID. sl@0: @note There is no need to supply CR, LF. If these are supplied it may cause the log output to be incorrect. sl@0: */ sl@0: { sl@0: if (!IsLogging()) sl@0: { sl@0: return; sl@0: } sl@0: sl@0: TPtrC16 textValid; sl@0: textValid.Set(aText.Left(KLogBufferSize)); sl@0: TBuf8 buf; sl@0: CnvUtfConverter::ConvertFromUnicodeToUtf8(buf,textValid); sl@0: DoWrite(buf); sl@0: } sl@0: sl@0: EXPORT_C void RFileLogger::WriteFormat(TRefByValue aFmt,...) sl@0: /** sl@0: * Write the formatted 16-bit string aFmt to the log file sl@0: * @internalTechnology sl@0: * @pre The client requesting to log must be listed in the flogger "ini" file sl@0: * as an enabled logging client, otherwise no logging will occur. sl@0: * The session with the server must be active, otherwise this will fail silently. sl@0: * @param aFmt c-style format descriptor, followed by any variables required by the format. sl@0: * @post The 16-bit text is converted to 8-bit text before writing, and is truncated to KLogBufferSize sl@0: * if necessary. sl@0: * The text is preceded in the log file by the two client tags and the client thread ID. sl@0: */ sl@0: { sl@0: if (!IsLogging()) sl@0: { sl@0: return; sl@0: } sl@0: //coverity[var_decl] sl@0: VA_LIST list; sl@0: VA_START(list,aFmt); sl@0: //coverity[uninit_use_in_call] sl@0: DoWriteFormat(aFmt,list); sl@0: sl@0: } sl@0: sl@0: EXPORT_C void RFileLogger::WriteFormat(TRefByValue aFmt, VA_LIST& aList) sl@0: /** sl@0: * Write the formatted 16-bit string aFmt to the log file. sl@0: * @internalTechnology sl@0: * @pre The client requesting to log must be listed in the flogger "ini" file sl@0: * as an enabled logging client, otherwise no logging will occur. sl@0: * The session with the server must be active, otherwise this will fail silently. sl@0: * @param aFmt c-style format descriptor sl@0: * @param aList any variables required by the format. sl@0: * @post The 16-bit text is converted to 8-bit text before writing, and is truncated to KLogBufferSize sl@0: * if necessary. sl@0: * The text is preceded in the log file by the two client tags and the client thread ID. sl@0: */ sl@0: { sl@0: if (IsLogging()) sl@0: { sl@0: DoWriteFormat(aFmt,aList); sl@0: } sl@0: } sl@0: sl@0: // sl@0: // 8-bit non-static writes sl@0: // sl@0: sl@0: EXPORT_C void RFileLogger::Write(const TDesC8& aText) sl@0: /** sl@0: * Write 8-bit aText to the log file. sl@0: * @internalTechnology sl@0: * @pre The client requesting to log must be listed in the flogger "ini" file sl@0: * as an enabled logging client, otherwise no logging will occur. sl@0: * The session with the server must be active, otherwise this will fail silently. sl@0: * @param aText Text to log. sl@0: * @post The text is truncated to KLogBufferSize if necessary. sl@0: * The text is preceded in the log file by the two client tags and the client thread ID. sl@0: */ sl@0: { sl@0: TPtrC8 textValid; sl@0: textValid.Set(aText.Left(KLogBufferSize)); sl@0: if (IsLogging()) sl@0: { sl@0: DoWrite(textValid); sl@0: } sl@0: } sl@0: sl@0: EXPORT_C void RFileLogger::WriteFormat(TRefByValue aFmt,...) sl@0: /** sl@0: * Write the formatted 8-bit string aFmt to the log file. sl@0: * @internalTechnology sl@0: * @pre The client requesting to log must be listed in the flogger "ini" file sl@0: * as an enabled logging client, otherwise no logging will occur. sl@0: * The session with the server must be active, otherwise this will fail silently. sl@0: * @param aFmt c-style format descriptor, followed by any variables required by the format. sl@0: * @post The text is truncated to KLogBufferSize if necessary. sl@0: * The text is preceded in the log file by the two client tags and the client thread ID. sl@0: */ sl@0: { sl@0: if (!IsLogging()) sl@0: { sl@0: return; sl@0: } sl@0: //coverity[var_decl] sl@0: VA_LIST list; sl@0: VA_START(list,aFmt); sl@0: //coverity[uninit_use_in_call] sl@0: DoWriteFormat(aFmt,list); sl@0: } sl@0: sl@0: EXPORT_C void RFileLogger::WriteFormat(TRefByValue aFmt, VA_LIST& aList) sl@0: /** sl@0: * Write the formatted 8-bit string aFmt to the log file if it is a valid file. sl@0: * @internalTechnology sl@0: * @pre The client requesting to log must be listed in the flogger "ini" file sl@0: * as an enabled logging client, otherwise no logging will occur. sl@0: * The session with the server must be active, otherwise this will fail silently. sl@0: * @param aFmt c-style format descriptor sl@0: * @param aList any variables required by the format. sl@0: * @post The text is truncated to KLogBufferSize if necessary. sl@0: * The text is preceded in the log file by the two client tags and the client thread ID. sl@0: */ sl@0: { sl@0: if (IsLogging()) sl@0: { sl@0: DoWriteFormat(aFmt,aList); sl@0: } sl@0: } sl@0: sl@0: EXPORT_C void RFileLogger::WriteBinary(const TDesC8& aData) sl@0: /** sl@0: * Dump arbitrary data to the log file in a binary format. sl@0: * @internalTechnology sl@0: * @pre The client requesting to log must be listed in the flogger "ini" file sl@0: * as an enabled logging client, otherwise no logging will occur. sl@0: * The session with the server must be active, otherwise this will fail silently. sl@0: * @param aData Descriptor of the data to be dumped sl@0: * @post The 8-bit binary dump is preceded in the log file by the two client tags sl@0: * sl@0: * @note Unlike all other write API's, no thread ID is written with this API. sl@0: */ sl@0: { sl@0: if (IsLogging()) sl@0: { sl@0: __ASSERT_ALWAYS(iLoggerBody,User::Panic(KFloggerPanic, EInternalConsistencyFault)); sl@0: (void)iLoggerBody->DoSendReceive(EWriteBinary, TIpcArgs(&aData, aData.Length())); sl@0: } sl@0: } sl@0: sl@0: sl@0: // sl@0: // 16-bit static writes sl@0: // sl@0: sl@0: EXPORT_C void RFileLogger::Write(const TDesC8& aSubsystem, const TDesC8& aComponent, const TDesC16& aText) sl@0: /** sl@0: * Static write. Write 16-bit aText to the log file if it is a valid file. sl@0: * @internalTechnology sl@0: @pre The client requesting to log must be listed in the flogger "ini" file sl@0: as an enabled logging client, otherwise no logging will occur. sl@0: * @param aSubsystem Specifies the tag1 name that goes into the log file sl@0: * @param aComponent specifies the tag2 name that goes into the log file sl@0: * @param aMode not used sl@0: * @param aText Text to write sl@0: * @post The text is converted to 8-bit text before writing, and truncated to KLogBufferSize if necessary. sl@0: * The text is preceded in the log file by the two client tags and the client thread ID. sl@0: * "aSubsystem" and "aComponent" are each truncated to KMaxTagLength. sl@0: * @note This function has poor performance since it performs a full connection and disconnection to the flogger server. sl@0: */ sl@0: { sl@0: // truncate tags sl@0: TPtrC8 validSubsystem; sl@0: TPtrC8 validComponent; sl@0: sl@0: validSubsystem.Set(aSubsystem.Left(KMaxTagLength)); sl@0: validComponent.Set(aComponent.Left(KMaxTagLength)); sl@0: sl@0: TBuf8 buf; sl@0: CnvUtfConverter::ConvertFromUnicodeToUtf8(buf,aText); sl@0: sl@0: DoStaticWrite(validSubsystem, validComponent, buf); sl@0: } sl@0: sl@0: EXPORT_C void RFileLogger::WriteFormat(const TDesC8& aSubsystem, const TDesC8& aComponent, const TRefByValue aFmt,...) sl@0: /** sl@0: * Static write. Write the formatted 16-bit string aFmt to the log file. sl@0: * @internalTechnology sl@0: @pre The client requesting to log must be listed in the flogger "ini" file sl@0: as an enabled logging client, otherwise no logging will occur. sl@0: * @param aSubsystem Specifies the tag1 name that goes into the log file sl@0: * @param aComponent specifies the tag2 name that goes into the log file sl@0: * @param aFmt c-style format descriptor, followed by any variables required by the format. sl@0: * @post The text is converted to 8-bit text before writing, and truncated to KLogBufferSize if necessary. sl@0: * The text is preceded in the log file by the two client tags and the client thread ID. sl@0: * "aSubsystem" and "aComponent" are each truncated to KMaxTagLength. sl@0: * @note This function has poor performance since it performs a full connection and disconnection to the flogger server. sl@0: */ sl@0: { sl@0: //coverity[var_decl] sl@0: VA_LIST list; sl@0: VA_START(list,aFmt); sl@0: sl@0: // truncate tags sl@0: TPtrC8 validSubsystem; sl@0: TPtrC8 validComponent; sl@0: sl@0: validSubsystem.Set(aSubsystem.Left(KMaxTagLength)); sl@0: validComponent.Set(aComponent.Left(KMaxTagLength)); sl@0: //coverity[uninit_use_in_call] sl@0: DoStaticWriteFormat(validSubsystem,validComponent,aFmt,list); sl@0: } sl@0: sl@0: EXPORT_C void RFileLogger::WriteFormat(const TDesC8& aSubsystem, const TDesC8& aComponent, const TRefByValue aFmt, VA_LIST& aList) sl@0: /** sl@0: * Static write. Write the formatted 16-bit string aFmt to the log file. sl@0: * @internalTechnology sl@0: @pre The client requesting to log must be listed in the flogger "ini" file sl@0: as an enabled logging client, otherwise no logging will occur. sl@0: * @param aSubsystem Specifies the tag1 name that goes into the log file sl@0: * @param aComponent specifies the tag2 name that goes into the log file sl@0: * @param aFmt c-style format descriptor sl@0: * @param aList any variables required by the format. sl@0: * @post The text is converted to 8-bit text before writing, and truncated to KLogBufferSize if necessary. sl@0: * The text is preceded in the log file by the two client tags and the client thread ID. sl@0: * "aSubsystem" and "aComponent" are each truncated to KMaxTagLength. sl@0: * @note This function has poor performance since it performs a full connection and disconnection to the flogger server. sl@0: */ sl@0: { sl@0: // truncate tags sl@0: TPtrC8 validSubsystem; sl@0: TPtrC8 validComponent; sl@0: sl@0: validSubsystem.Set(aSubsystem.Left(KMaxTagLength)); sl@0: validComponent.Set(aComponent.Left(KMaxTagLength)); sl@0: sl@0: DoStaticWriteFormat(validSubsystem,validComponent,aFmt,aList); sl@0: } sl@0: sl@0: // sl@0: // 8-bit static writes sl@0: // sl@0: sl@0: EXPORT_C void RFileLogger::Write(const TDesC8& aSubsystem, const TDesC8& aComponent, const TDesC8& aText) sl@0: /** sl@0: * Static write. Write 8-bit aText to the log file. sl@0: * @internalTechnology sl@0: @pre The client requesting to log must be listed in the flogger "ini" file sl@0: as an enabled logging client, otherwise no logging will occur. sl@0: * @param aSubsystem Specifies the tag1 name that goes into the log file sl@0: * @param aComponent specifies the tag2 name that goes into the log file sl@0: * @param aText Text to log. sl@0: * @post The text is truncated to KLogBufferSize if necessary. sl@0: * The text is preceded in the log file by the two client tags and the client thread ID. sl@0: * "aSubsystem" and "aComponent" are each truncated to KMaxTagLength. sl@0: * @note This function has poor performance since it performs a full connection and disconnection to the flogger server. sl@0: */ sl@0: { sl@0: // truncate tags sl@0: TPtrC8 validSubsystem; sl@0: TPtrC8 validComponent; sl@0: sl@0: validSubsystem.Set(aSubsystem.Left(KMaxTagLength)); sl@0: validComponent.Set(aComponent.Left(KMaxTagLength)); sl@0: DoStaticWrite(validSubsystem,validComponent, aText); sl@0: } sl@0: sl@0: EXPORT_C void RFileLogger::WriteFormat(const TDesC8& aSubsystem, const TDesC8& aComponent, const TRefByValue aFmt,...) sl@0: /** sl@0: * Static write. Write the formatted 8-bit string aFmt to the log file. sl@0: * @internalTechnology sl@0: @pre The client requesting to log must be listed in the flogger "ini" file sl@0: as an enabled logging client, otherwise no logging will occur. sl@0: * @param aSubsystem Specifies the tag1 name that goes into the log file sl@0: * @param aComponent specifies the tag2 name that goes into the log file sl@0: * @param aFmt c-style format descriptor, followed by any variables required by the format. sl@0: * @post The text is truncated to KLogBufferSize if necessary. sl@0: * The text is preceded in the log file by the two client tags and the client thread ID. sl@0: * "aSubsystem" and "aComponent" are each truncated to KMaxTagLength. sl@0: * @note This function has poor performance since it performs a full connection and disconnection to the flogger server. sl@0: */ sl@0: sl@0: { sl@0: //coverity[var_decl] sl@0: VA_LIST list; sl@0: VA_START(list,aFmt); sl@0: sl@0: // truncate tags sl@0: TPtrC8 validSubsystem; sl@0: TPtrC8 validComponent; sl@0: sl@0: validSubsystem.Set(aSubsystem.Left(KMaxTagLength)); sl@0: validComponent.Set(aComponent.Left(KMaxTagLength)); sl@0: //coverity[uninit_use_in_call] sl@0: DoStaticWriteFormat(validSubsystem,validComponent,aFmt,list); sl@0: } sl@0: sl@0: EXPORT_C void RFileLogger::WriteFormat(const TDesC8& aSubsystem, const TDesC8& aComponent, const TRefByValue aFmt, VA_LIST& aList) sl@0: /** sl@0: * Static write. Write the formatted 16-bit string aFmt to the log file. sl@0: * @internalTechnology sl@0: @pre The client requesting to log must be listed in the flogger "ini" file sl@0: as an enabled logging client, otherwise no logging will occur. sl@0: * @param aSubsystem Specifies the tag1 name that goes into the log file sl@0: * @param aComponent specifies the tag2 name that goes into the log file sl@0: * @param aFmt c-style format descriptor sl@0: * @param aList any variables required by the format. sl@0: * @post The text is truncated to KLogBufferSize if necessary. sl@0: * The text is preceded in the log file by the two client tags and the client thread ID. sl@0: * "aSubsystem" and "aComponent" are each truncated to KMaxTagLength. sl@0: * @note This function has poor performance since it performs a full connection and disconnection to the flogger server. sl@0: */ sl@0: { sl@0: //truncate tags sl@0: TPtrC8 validSubsystem; sl@0: TPtrC8 validComponent; sl@0: sl@0: validSubsystem.Set(aSubsystem.Left(KMaxTagLength)); sl@0: validComponent.Set(aComponent.Left(KMaxTagLength)); sl@0: sl@0: DoStaticWriteFormat(validSubsystem,validComponent,aFmt,aList); sl@0: } sl@0: sl@0: sl@0: sl@0: sl@0: sl@0: sl@0: // sl@0: // Removed 16-bit static writes sl@0: // sl@0: sl@0: EXPORT_C void RFileLogger::Write(const TDesC& aSubsystem, const TDesC& aComponent, TFileLoggingMode /*aMode*/, const TDesC16& aText) sl@0: /** sl@0: * Static write. Write 16-bit aText to the log file if it is a valid file. sl@0: * @internalTechnology sl@0: * @removed With the advent of a single log file for all clients, this function has been replaced by an equivalent without the aMode parameter. sl@0: @pre The client requesting to log must be listed in the flogger "ini" file sl@0: as an enabled logging client, otherwise no logging will occur. sl@0: * @param aSubsystem Specifies the tag1 name that goes into the log file sl@0: * @param aComponent specifies the tag2 name that goes into the log file sl@0: * @param aMode not used sl@0: * @param aText Text to write sl@0: * @post The text is converted to 8-bit text before writing, and truncated to KLogBufferSize if necessary. sl@0: * The text is preceded in the log file by the two client tags and the client thread ID. sl@0: * "aSubsystem" and "aComponent" are each truncated to KMaxTagLength. sl@0: * @note This function has poor performance since it performs a full connection and disconnection to the flogger server. sl@0: */ sl@0: { sl@0: // the convert also truncates if necessary sl@0: TNameTag narrowComponent; sl@0: CnvUtfConverter::ConvertFromUnicodeToUtf8(narrowComponent,aComponent); sl@0: TNameTag narrowSubsystem; sl@0: CnvUtfConverter::ConvertFromUnicodeToUtf8(narrowSubsystem,aSubsystem); sl@0: sl@0: Write(narrowSubsystem, narrowComponent, aText); sl@0: } sl@0: sl@0: EXPORT_C void RFileLogger::WriteFormat(const TDesC& aSubsystem, const TDesC& aComponent, TFileLoggingMode aMode, TRefByValue aFmt,...) sl@0: /** sl@0: * Static write. Write the formatted 16-bit string aFmt to the log file. sl@0: * @internalTechnology sl@0: * @removed With the advent of a single log file for all clients, this function has been replaced by an equivalent without the aMode parameter. sl@0: @pre The client requesting to log must be listed in the flogger "ini" file sl@0: as an enabled logging client, otherwise no logging will occur. sl@0: * @param aSubsystem Specifies the tag1 name that goes into the log file sl@0: * @param aComponent specifies the tag2 name that goes into the log file sl@0: * @param aMode not used sl@0: * @param aFmt c-style format descriptor, followed by any variables required by the format. sl@0: * @post The text is converted to 8-bit text before writing, and truncated to KLogBufferSize if necessary. sl@0: * The text is preceded in the log file by the two client tags and the client thread ID. sl@0: * "aSubsystem" and "aComponent" are each truncated to KMaxTagLength. sl@0: * @note This function has poor performance since it performs a full connection and disconnection to the flogger server. sl@0: */ sl@0: { sl@0: // Just to remove the warning otherwise this does nothing sl@0: if (aMode == EFileLoggingModeUnknown) { } sl@0: //coverity[var_decl] sl@0: VA_LIST list; sl@0: VA_START(list,aFmt); sl@0: sl@0: // the convert also truncates if necessary sl@0: TNameTag narrowComponent; sl@0: CnvUtfConverter::ConvertFromUnicodeToUtf8(narrowComponent,aComponent); sl@0: TNameTag narrowSubsystem; sl@0: CnvUtfConverter::ConvertFromUnicodeToUtf8(narrowSubsystem,aSubsystem); sl@0: //coverity[uninit_use_in_call] sl@0: DoStaticWriteFormat(narrowSubsystem, narrowComponent,aFmt,list); sl@0: } sl@0: sl@0: EXPORT_C void RFileLogger::WriteFormat(const TDesC& aSubsystem, const TDesC& aComponent, TFileLoggingMode /*aMode*/, TRefByValue aFmt, VA_LIST& aList) sl@0: /** sl@0: * Static write. Write the formatted 16-bit string aFmt to the log file. sl@0: * @internalTechnology sl@0: * @removed With the advent of a single log file for all clients, this function has been replaced by an equivalent without the aMode parameter. sl@0: @pre The client requesting to log must be listed in the flogger "ini" file sl@0: as an enabled logging client, otherwise no logging will occur. sl@0: * @param aSubsystem Specifies the tag1 name that goes into the log file sl@0: * @param aComponent specifies the tag2 name that goes into the log file sl@0: * @param aMode not used sl@0: * @param aFmt c-style format descriptor sl@0: * @param aList any variables required by the format. sl@0: * @post The text is converted to 8-bit text before writing, and truncated to KLogBufferSize if necessary. sl@0: * The text is preceded in the log file by the two client tags and the client thread ID. sl@0: * "aSubsystem" and "aComponent" are each truncated to KMaxTagLength. sl@0: * @note This function has poor performance since it performs a full connection and disconnection to the flogger server. sl@0: */ sl@0: { sl@0: // the convert also truncates if necessary sl@0: TNameTag narrowComponent; sl@0: CnvUtfConverter::ConvertFromUnicodeToUtf8(narrowComponent,aComponent); sl@0: TNameTag narrowSubsystem; sl@0: CnvUtfConverter::ConvertFromUnicodeToUtf8(narrowSubsystem,aSubsystem); sl@0: sl@0: DoStaticWriteFormat(narrowSubsystem, narrowComponent,aFmt,aList); sl@0: } sl@0: sl@0: // sl@0: // Removed 8-bit static writes sl@0: // sl@0: sl@0: EXPORT_C void RFileLogger::Write(const TDesC& aSubsystem, const TDesC& aComponent, TFileLoggingMode /*aMode*/, const TDesC8& aText) sl@0: /** sl@0: * Static write. Write 8-bit aText to the log file. sl@0: * @internalTechnology sl@0: * @removed With the advent of a single log file for all clients, this function has been replaced by an equivalent without the aMode parameter. sl@0: @pre The client requesting to log must be listed in the flogger "ini" file sl@0: as an enabled logging client, otherwise no logging will occur. sl@0: * @param aSubsystem Specifies the tag1 name that goes into the log file sl@0: * @param aComponent specifies the tag2 name that goes into the log file sl@0: * @param aMode not used sl@0: * @param aText Text to log. sl@0: * @post The text is truncated to KLogBufferSize if necessary. sl@0: * The text is preceded in the log file by the two client tags and the client thread ID. sl@0: * "aSubsystem" and "aComponent" are each truncated to KMaxTagLength. sl@0: * @note This function has poor performance since it performs a full connection and disconnection to the flogger server. sl@0: */ sl@0: { sl@0: // the convert also truncates if necessary sl@0: TNameTag narrowComponent; sl@0: CnvUtfConverter::ConvertFromUnicodeToUtf8(narrowComponent,aComponent); sl@0: TNameTag narrowSubsystem; sl@0: CnvUtfConverter::ConvertFromUnicodeToUtf8(narrowSubsystem,aSubsystem); sl@0: sl@0: Write(narrowSubsystem, narrowComponent, aText); sl@0: } sl@0: sl@0: EXPORT_C void RFileLogger::WriteFormat(const TDesC& aSubsystem, const TDesC& aComponent, TFileLoggingMode aMode, TRefByValue aFmt,...) sl@0: /** sl@0: * Static write. Write the formatted 8-bit string aFmt to the log file. sl@0: * @internalTechnology sl@0: * @removed With the advent of a single log file for all clients, this function has been replaced by an equivalent without the aMode parameter. sl@0: @pre The client requesting to log must be listed in the flogger "ini" file sl@0: as an enabled logging client, otherwise no logging will occur. sl@0: * @param aSubsystem Specifies the tag1 name that goes into the log file sl@0: * @param aComponent specifies the tag2 name that goes into the log file sl@0: * @param aMode not used sl@0: * @param aFmt c-style format descriptor, followed by any variables required by the format. sl@0: * @post The text is truncated to KLogBufferSize if necessary. sl@0: * The text is preceded in the log file by the two client tags and the client thread ID. sl@0: * "aSubsystem" and "aComponent" are each truncated to KMaxTagLength. sl@0: * @note This function has poor performance since it performs a full connection and disconnection to the flogger server. sl@0: */ sl@0: sl@0: { sl@0: // Just to remove the warning otherwise this does nothing sl@0: if (aMode == EFileLoggingModeUnknown) { } sl@0: //coverity[var_decl] sl@0: VA_LIST list; sl@0: VA_START(list,aFmt); sl@0: sl@0: // the convert also truncates if necessary sl@0: TNameTag narrowComponent; sl@0: CnvUtfConverter::ConvertFromUnicodeToUtf8(narrowComponent,aComponent); sl@0: TNameTag narrowSubsystem; sl@0: CnvUtfConverter::ConvertFromUnicodeToUtf8(narrowSubsystem,aSubsystem); sl@0: //coverity[uninit_use_in_call] sl@0: DoStaticWriteFormat(narrowSubsystem, narrowComponent, aFmt, list); sl@0: } sl@0: sl@0: EXPORT_C void RFileLogger::WriteFormat(const TDesC& aSubsystem, const TDesC& aComponent, TFileLoggingMode /*aMode*/, TRefByValue aFmt, VA_LIST& aList) sl@0: /** sl@0: * Static write. Write the formatted 16-bit string aFmt to the log file. sl@0: * @internalTechnology sl@0: * @removed With the advent of a single log file for all clients, this function has been replaced by an equivalent without the aMode parameter. sl@0: @pre The client requesting to log must be listed in the flogger "ini" file sl@0: as an enabled logging client, otherwise no logging will occur. sl@0: * @param aSubsystem Specifies the tag1 name that goes into the log file sl@0: * @param aComponent specifies the tag2 name that goes into the log file sl@0: * @param aMode not used sl@0: * @param aFmt c-style format descriptor sl@0: * @param aList any variables required by the format. sl@0: * @post The text is truncated to KLogBufferSize if necessary. sl@0: * The text is preceded in the log file by the two client tags and the client thread ID. sl@0: * "aSubsystem" and "aComponent" are each truncated to KMaxTagLength. sl@0: * @note This function has poor performance since it performs a full connection and disconnection to the flogger server. sl@0: */ sl@0: { sl@0: // the convert also truncates if necessary sl@0: TNameTag narrowComponent; sl@0: CnvUtfConverter::ConvertFromUnicodeToUtf8(narrowComponent,aComponent); sl@0: TNameTag narrowSubsystem; sl@0: CnvUtfConverter::ConvertFromUnicodeToUtf8(narrowSubsystem,aSubsystem); sl@0: sl@0: DoStaticWriteFormat(narrowSubsystem, narrowComponent,aFmt,aList); sl@0: } sl@0: sl@0: // sl@0: // Hex Dumps sl@0: // sl@0: sl@0: EXPORT_C void RFileLogger::HexDump(const TText* aHeader, const TText* aMargin, const TUint8* aPtr, TInt aLen) sl@0: /** sl@0: * Dump arbitrary data to the log file as a standard hex dump. sl@0: * @internalTechnology sl@0: * @pre The session with the server must be active, otherwise this no action is taken. sl@0: The client requesting to log must be listed in the flogger "ini" file sl@0: as an enabled logging client, otherwise no logging will occur. sl@0: * @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. sl@0: * @param aMargin Specify a zero-terminated string to be printed before each subsequent line. Leave as null or an empty string for no Margin. sl@0: * @param aPtr pointer to the data being dumped. sl@0: * @param aLen the number of bytes to dump sl@0: * @post Each line is preceded in the log file by the two client tags and the client thread ID. sl@0: * @note Example of aHeader/aMargin. If "aHeader" is set to "Fn Output:" and "aMargin" is set to " ", then output would look sl@0: * like (for a print of the alphabet): sl@0: * TLOG Example 20 FnOutput:0000 : 61 62 63 64 65 66 67 68 69 6a 6b 6c 6d 6e 6f 70 abcdefghijklmnop sl@0: * TLOG Example 20 0010 : 71 72 73 74 75 76 77 78 79 7a qrstuvwxyz sl@0: * sl@0: */ sl@0: { sl@0: if (IsLogging()) sl@0: { sl@0: DoHexDump(aHeader,aMargin,aPtr,aLen); sl@0: } sl@0: sl@0: sl@0: } sl@0: sl@0: sl@0: sl@0: EXPORT_C void RFileLogger::HexDump(const TDesC8& aData, const TDesC8& aHeader) sl@0: /** sl@0: * Dump arbitrary data to the log file as a standard hex dump. sl@0: * @internalTechnology sl@0: * @pre The session with the server must be active, otherwise this no action is taken. sl@0: The client requesting to log must be listed in the flogger "ini" file sl@0: as an enabled logging client, otherwise no logging will occur. sl@0: * @param aData the data being dumped. sl@0: * @param aHeader Specify a string to be printed before the first hex line. If not supplied, no header or margin is written. sl@0: * If supplied, then subsequent lines are indented to the length of aHeader. sl@0: * @post Each line is preceded in the log file by the two client tags and the client thread ID. sl@0: * @note Example of aHeader. If "aHeader" is set to "Fn Output:" then output would look sl@0: * like (for a print of the alphabet): sl@0: * TLOG Example 20 FnOutput:0000 : 61 62 63 64 65 66 67 68 69 6a 6b 6c 6d 6e 6f 70 abcdefghijklmnop sl@0: * TLOG Example 20 0010 : 71 72 73 74 75 76 77 78 79 7a qrstuvwxyz sl@0: * sl@0: */ sl@0: { sl@0: if (IsLogging()) sl@0: { sl@0: DoHexDump(aData,aHeader,TPtrC8(NULL,0)); sl@0: } sl@0: sl@0: sl@0: } sl@0: sl@0: sl@0: sl@0: sl@0: sl@0: sl@0: EXPORT_C void RFileLogger::HexDump(const TDesC8& aSubsystem, const TDesC8& aComponent, const TDesC8& aData, const TDesC8& aHeader) sl@0: /** sl@0: * Static Write. Dump arbitrary data to the log file as a standard hex dump. sl@0: * @internalTechnology sl@0: @pre The client requesting to log must be listed in the flogger "ini" file sl@0: as an enabled logging client, otherwise no logging will occur. sl@0: * @param aSubsystem Specifies the tag1 name that goes into the log file sl@0: * @param aComponent specifies the tag2 name that goes into the log file sl@0: * @param aData the data being dumped. sl@0: * @param aHeader Specify a string to be printed before the first hex line. If not supplied, no header or Margin is written. sl@0: * @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. sl@0: * @post Each line is preceded in the log file by the two client tags and the client thread ID. sl@0: * "aSubsystem" and "aComponent" are each truncated to KMaxTagLength. sl@0: * @note This function has poor performance since it performs a full connection and disconnection to the flogger server. sl@0: * Example of aHeader/aMargin. If "aHeader" is set to "Fn Output:" and "aMargin" is set to " ", then output would look sl@0: * like (for a print of the alphabet): sl@0: * TLOG Example 20 FnOutput:0000 : 61 62 63 64 65 66 67 68 69 6a 6b 6c 6d 6e 6f 70 abcdefghijklmnop sl@0: * TLOG Example 20 0010 : 71 72 73 74 75 76 77 78 79 7a qrstuvwxyz sl@0: * sl@0: */ sl@0: { sl@0: RFileLogger logger; sl@0: TInt ret=logger.Connect(); sl@0: if (ret==KErrNone) sl@0: { sl@0: ret = logger.SetLogTags(aSubsystem,aComponent); sl@0: if (((ret == KErrNone) && logger.iLoggerBody) && logger.iLoggerBody->iLoggingOnPckg()) sl@0: { sl@0: logger.DoHexDump(aData,aHeader,TPtrC8(NULL,0)); sl@0: } sl@0: logger.Close(); sl@0: } sl@0: } sl@0: sl@0: sl@0: sl@0: sl@0: sl@0: EXPORT_C void RFileLogger::HexDump(const TDesC& aSubsystem, const TDesC& aComponent, TFileLoggingMode /*aMode*/, const TText* aHeader, const TText* aMargin, const TUint8* aPtr, TInt aLen) sl@0: /** sl@0: * Static Write. Dump arbitrary data to the log file as a standard hex dump. sl@0: * @internalTechnology sl@0: * @removed With the advent of a single log file for all clients, this function has been replaced by an equivalent without the aMode parameter. sl@0: @pre The client requesting to log must be listed in the flogger "ini" file sl@0: as an enabled logging client, otherwise no logging will occur. sl@0: * @param aSubsystem Specifies the tag1 name that goes into the log file sl@0: * @param aComponent specifies the tag2 name that goes into the log file sl@0: * @param aMode not used sl@0: * @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. sl@0: * @param aMargin Specify a zero-terminated string to be printed before each subsequent line. Leave as null or an empty string for no Margin. sl@0: * @param aPtr pointer to the data being dumped. sl@0: * @param aLen the number of bytes to dump sl@0: * @post Each line is preceded in the log file by the two client tags and the client thread ID. sl@0: * "aSubsystem" and "aComponent" are each truncated to KMaxTagLength. sl@0: * @note This function has poor performance since it performs a full connection and disconnection to the flogger server. sl@0: * Example of aHeader/aMargin. If "aHeader" is set to "Fn Output:" and "aMargin" is set to " ", then output would look sl@0: * like (for a print of the alphabet): sl@0: * TLOG Example 20 FnOutput:0000 : 61 62 63 64 65 66 67 68 69 6a 6b 6c 6d 6e 6f 70 abcdefghijklmnop sl@0: * TLOG Example 20 0010 : 71 72 73 74 75 76 77 78 79 7a qrstuvwxyz sl@0: * sl@0: */ sl@0: { sl@0: // the convert also truncates if necessary sl@0: TNameTag narrowComponent; sl@0: CnvUtfConverter::ConvertFromUnicodeToUtf8(narrowComponent,aComponent); sl@0: TNameTag narrowSubsystem; sl@0: CnvUtfConverter::ConvertFromUnicodeToUtf8(narrowSubsystem,aSubsystem); sl@0: sl@0: RFileLogger logger; sl@0: TInt ret=logger.Connect(); sl@0: if (ret==KErrNone) sl@0: { sl@0: ret = logger.SetLogTags(narrowSubsystem,narrowComponent); sl@0: if (((ret == KErrNone) && logger.iLoggerBody) && logger.iLoggerBody->iLoggingOnPckg()) sl@0: { sl@0: logger.DoHexDump(aHeader,aMargin,aPtr,aLen); sl@0: } sl@0: logger.Close(); sl@0: } sl@0: sl@0: } sl@0: sl@0: sl@0: EXPORT_C TInt RFileLogger::Handle() const sl@0: // Returns handle of session, or Null if no session. sl@0: { sl@0: if (iLoggerBody) sl@0: { sl@0: return iLoggerBody->Handle(); sl@0: } sl@0: else sl@0: { sl@0: return 0; sl@0: } sl@0: } sl@0: sl@0: EXPORT_C TInt RFileLogger::Share() sl@0: { sl@0: if (iLoggerBody) sl@0: { sl@0: return iLoggerBody->ShareAuto(); sl@0: } sl@0: return KErrSessionClosed; sl@0: } sl@0: sl@0: sl@0: // sl@0: // Debug tools to check for memory leaks sl@0: // sl@0: sl@0: EXPORT_C void RFileLogger::__DbgShutDownServer() sl@0: /** sl@0: * Debugging Tool. Ask the flogger server to shutdown. Only valid in DEBUG builds. sl@0: * @internalTechnology sl@0: */ sl@0: { sl@0: #ifdef _DEBUG sl@0: if (iLoggerBody) sl@0: (void)iLoggerBody->DoSendReceive(EShutDownServer); sl@0: #endif sl@0: } sl@0: sl@0: EXPORT_C void RFileLogger::__DbgSetHeapFailure(TInt aFailAfter) sl@0: /** sl@0: * Debugging Tool. Ask the flogger server to set its heap failure. Only valid in DEBUG builds. sl@0: * @internalTechnology sl@0: * @param aFailAfter The number of successful memory allocations which will occur before sl@0: * a memory allocation is failed by the memory manager. sl@0: */ sl@0: { sl@0: #ifdef _DEBUG sl@0: if (iLoggerBody) sl@0: { sl@0: (void)iLoggerBody->DoSendReceive(ESetHeapFailure, TIpcArgs(aFailAfter)); sl@0: } sl@0: #else sl@0: (void)aFailAfter; sl@0: #endif sl@0: } sl@0: sl@0: // sl@0: // Private functions sl@0: // sl@0: sl@0: TInt RFileLogger::DoConnect() sl@0: /** sl@0: * Connect to the flogger server sl@0: * @return TInt indicating success code (KErrNone) or an error code. sl@0: * @note: creates 1 slot: no asynchronous IPC so never need more than 1 reserved message slot. sl@0: @internalComponent sl@0: */ sl@0: { sl@0: __ASSERT_ALWAYS(iLoggerBody,User::Panic(KFloggerPanic, EInternalConsistencyFault)); sl@0: return iLoggerBody->DoCreateSession(KFLoggerServerName,Version(),KNumberMessageSlots); sl@0: } sl@0: sl@0: TInt RFileLogger::DoSetLogTags(const TDesC8& aSubsystem, const TDesC8& aComponent) sl@0: /** sl@0: * Set the two tag strings that all further writes by this client will use to sl@0: * identify it in the log file. sl@0: * @param aSubsystem Specifies the tag1 name that goes into the log file sl@0: * @param aComponent specifies the tag2 name that goes into the log file sl@0: * @return TInt indicating success code (KErrNone), or (KErrNotFound) if sl@0: the connection is not valid, or an error code from SendReceive. sl@0: * @note If an error occurs, the client connection will be silently closed to protect sl@0: * the client. sl@0: */ sl@0: { sl@0: TInt err(KErrNone); sl@0: if (iLoggerBody) //check that the connection was set up correctly sl@0: { sl@0: err = iLoggerBody->DoSendReceive(ESetLogTag, TIpcArgs(&aSubsystem, &aComponent, &(iLoggerBody->iLoggingOnPckg))); sl@0: if (err !=KErrNone ) sl@0: { //Something went wrong. We need to protect the client because error can be ignored. sl@0: Close(); sl@0: } sl@0: } sl@0: else sl@0: { sl@0: err = KErrNotFound; sl@0: } sl@0: return err; sl@0: } sl@0: sl@0: void RFileLogger::DoWrite(const TDesC8& aBuf) sl@0: /** sl@0: * Send to the flogger server the pre-formatted write string. sl@0: * @internalTechnology sl@0: * @pre session is already open. sl@0: * @param aBuf 8-bit text to be written. It must not exceed KLogBufferSize. sl@0: */ sl@0: { sl@0: __ASSERT_ALWAYS(iLoggerBody,User::Panic(KFloggerPanic, EInternalConsistencyFault)); sl@0: (void)iLoggerBody->DoSendReceive(EWriteToLog,TIpcArgs(&aBuf, aBuf.Length())); sl@0: } sl@0: sl@0: void RFileLogger::DoWriteFormat(TRefByValue aFmt, VA_LIST& aList) sl@0: /** sl@0: * Trim and convert format string before sending to the flogger server. sl@0: * @pre session is already open. sl@0: * @param aFmt c-style formatted text to be written. sl@0: * @param aList any variables required by the format. sl@0: * @post The final string is truncated to KLogBufferSize and converted to 8-bit. sl@0: */ sl@0: { sl@0: TBuf16 wideBuf; sl@0: __ASSERT_ALWAYS(iLoggerBody,User::Panic(KFloggerPanic, EInternalConsistencyFault)); sl@0: wideBuf.AppendFormatList(aFmt, aList, &(iLoggerBody->iFlogOverflow16)); sl@0: TBuf8 narrowBuf; sl@0: CnvUtfConverter::ConvertFromUnicodeToUtf8(narrowBuf,wideBuf); sl@0: DoWrite(narrowBuf); sl@0: } sl@0: sl@0: void RFileLogger::DoWriteFormat(TRefByValue aFmt, VA_LIST& aList) sl@0: /** sl@0: * Trim format string before sending to the flogger server. sl@0: * @pre session is already open. sl@0: * @param aFmt c-style formatted text to be written. sl@0: * @param aList any variables required by the format. sl@0: * @post The final string is truncated to KLogBufferSize. sl@0: */ sl@0: { sl@0: TBuf8 buf; sl@0: __ASSERT_ALWAYS(iLoggerBody,User::Panic(KFloggerPanic, EInternalConsistencyFault)); sl@0: buf.AppendFormatList(aFmt,aList, &(iLoggerBody->iFlogOverflow8)); sl@0: DoWrite(buf); sl@0: } sl@0: sl@0: void RFileLogger::DoSendStaticWrite(const TDesC8& aSubsystem, const TDesC8& aComponent, const TDesC8& aText) sl@0: /** sl@0: * Send to the flogger server the pre-formatted write string. sl@0: * @pre session is already open. sl@0: * aText is not longer than KLogBufferSize sl@0: * @param aSubsystem Specifies the tag1 name that goes into the log file sl@0: * @param aComponent specifies the tag2 name that goes into the log file sl@0: * @param aText text to write sl@0: * @post The text is only written if the tag1+tag2 combination is listed as an enabled client sl@0: * in the flogger "ini" file, otherwise no action is taken. sl@0: * The text is preceded in the log file by the two client tags and the client thread ID. sl@0: */ sl@0: { sl@0: __ASSERT_ALWAYS(iLoggerBody,User::Panic(KFloggerPanic, EInternalConsistencyFault)); sl@0: (void)iLoggerBody->DoSendReceive(EStaticWriteToLog,TIpcArgs(&aSubsystem, &aComponent, &aText, aText.Length())); // ignore error sl@0: } sl@0: sl@0: void RFileLogger::DoStaticWrite(const TDesC8& aSubsystem, const TDesC8& aComponent, const TDesC8& aText) sl@0: /** sl@0: * Send to the flogger server the pre-formatted write string. sl@0: * @pre session is already open. sl@0: * aText is not longer than KLogBufferSize sl@0: * @param aSubsystem Specifies the tag1 name that goes into the log file sl@0: * @param aComponent specifies the tag2 name that goes into the log file sl@0: * @param aText text to write sl@0: * @post The text is only written if the tag1+tag2 combination is listed as an enabled client sl@0: * in the flogger "ini" file, otherwise no action is taken. sl@0: * The text is preceded in the log file by the two client tags and the client thread ID. sl@0: */ sl@0: { sl@0: RFileLogger logger; sl@0: TInt ret=logger.Connect(); sl@0: if (ret==KErrNone) sl@0: { sl@0: TPtrC8 textValid; sl@0: textValid.Set(aText.Left(KLogBufferSize)); sl@0: sl@0: logger.DoSendStaticWrite(aSubsystem, aComponent, textValid); sl@0: } sl@0: sl@0: logger.Close(); sl@0: } sl@0: sl@0: sl@0: sl@0: void RFileLogger::DoStaticWriteFormat(const TDesC8& aSubsystem, const TDesC8& aComponent, TRefByValue aFmt, VA_LIST& aList) sl@0: /** sl@0: * Send to the flogger server a format write string. sl@0: * @param aSubsystem Specifies the tag1 name that goes into the log file sl@0: * @param aComponent specifies the tag2 name that goes into the log file sl@0: * @param aFmt c-style formatted text to be written. sl@0: * @param aList any variables required by the format. sl@0: * @post The text is only written if the tag1+tag2 combination is listed as an enabled client sl@0: * in the flogger "ini" file, otherwise no action is taken. sl@0: * If necessary, the final string is truncated to KLogBufferSize. sl@0: * The final string is converted to an 8-bit string. sl@0: * The text is preceded in the log file by the two client tags and the client thread ID. sl@0: */ sl@0: { sl@0: TFlogOverflow16 objFlogBody16; sl@0: TBuf wideBuf; sl@0: TBuf8 narrowBuf; sl@0: sl@0: wideBuf.AppendFormatList(aFmt, aList, &objFlogBody16); sl@0: CnvUtfConverter::ConvertFromUnicodeToUtf8(narrowBuf,wideBuf); sl@0: sl@0: DoStaticWrite(aSubsystem, aComponent, narrowBuf); sl@0: } sl@0: sl@0: void RFileLogger::DoStaticWriteFormat(const TDesC8& aSubsystem, const TDesC8& aComponent, TRefByValue aFmt, VA_LIST& aList) sl@0: /** sl@0: * Send to the flogger server a format write string. sl@0: * @param aSubsystem Specifies the tag1 name that goes into the log file sl@0: * @param aComponent specifies the tag2 name that goes into the log file sl@0: * @param aFmt c-style formatted text to be written. sl@0: * @param aList any variables required by the format. sl@0: * @post The text is only written if the tag1+tag2 combination is listed as an enabled client sl@0: * in the flogger "ini" file, otherwise no action is taken. sl@0: * If necessary, the final string is truncated to KLogBufferSize. sl@0: * The text is preceded in the log file by the two client tags and the client thread ID. sl@0: */ { sl@0: TFlogOverflow8 objFlogBody8; sl@0: TBuf8 buf; sl@0: buf.AppendFormatList(aFmt, aList, &objFlogBody8); sl@0: sl@0: DoStaticWrite(aSubsystem, aComponent, buf); sl@0: } sl@0: sl@0: void RFileLogger::DoHexDump(const TText* aHeader, const TText* aMargin, const TUint8* aPtr, TInt aLen) sl@0: /** sl@0: * Static Write. Dump arbitrary data to the log file as a standard hex dump. sl@0: * @pre session is already open. sl@0: * @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. sl@0: * @param aMargin Specify a zero-terminated string to be printed before each subsequent line. Leave as null or an empty string for no Margin. sl@0: * @param aPtr pointer to the data being dumped. sl@0: * @param aLen the number of bytes to dump sl@0: * @post The text is only written if the tag1+tag2 combination is listed as an enabled client sl@0: * in the flogger "ini" file, otherwise no action is taken. sl@0: * Each line is preceded in the log file by the two client tags and the client thread ID. sl@0: * The data is written in lines of 16 characters. sl@0: * @note Example of aHeader/aMargin. If "aHeader" is set to "Fn Output:" and "aMargin" is set to " ", then output would look sl@0: * like (for a print of the alphabet): sl@0: * TLOG Example 20 FnOutput:0000 : 61 62 63 64 65 66 67 68 69 6a 6b 6c 6d 6e 6f 70 abcdefghijklmnop sl@0: * TLOG Example 20 0010 : 71 72 73 74 75 76 77 78 79 7a qrstuvwxyz sl@0: * sl@0: */ sl@0: { sl@0: // this delightful art-deco code lifted straight from old flogger sl@0: if (aPtr==NULL) // nothing to do sl@0: { sl@0: return; sl@0: } sl@0: sl@0: TBuf buf; sl@0: TBuf8 temp; sl@0: sl@0: sl@0: TInt i=0; sl@0: const TText* p=aHeader; sl@0: while (aLen>0) sl@0: { sl@0: if (p==NULL) sl@0: { sl@0: p=BLANK; // if NULL set p to a blank string sl@0: } sl@0: TInt n=(aLen>KHexDumpWidth ? KHexDumpWidth : aLen); sl@0: __ASSERT_ALWAYS(iLoggerBody,User::Panic(KFloggerPanic, EInternalConsistencyFault)); sl@0: buf.AppendFormat(KFirstFormatString,&(iLoggerBody->iFlogOverflow16),p,i); sl@0: TInt j; sl@0: for (j=0; jKHighestPrintableCharacter) ? KFullStopChar : aPtr[i+j]); sl@0: } sl@0: sl@0: CnvUtfConverter::ConvertFromUnicodeToUtf8(temp,buf); sl@0: DoWrite(temp); sl@0: sl@0: buf.SetLength(0); sl@0: temp.SetLength(0); sl@0: aLen-=n; sl@0: i+=n; sl@0: p=aMargin; sl@0: } sl@0: } sl@0: sl@0: sl@0: sl@0: void RFileLogger::DoHexDump(const TDesC8& aData, const TDesC8& aHeader, const TDesC8& aMargin) sl@0: /** sl@0: * Static Write. Dump arbitrary data to the log file as a standard hex dump. sl@0: * @see RFileLogger::HexDump(const TDesC8& aData, const TDesC8& aHeader = 0) sl@0: * @param aMargin - supply a margin - if left null, then a margin of spaces of equal length to "aHeader" sl@0: * is used. sl@0: * @pre session is already open. sl@0: */ sl@0: { sl@0: HBufC8* marginStr = NULL; sl@0: TBuf8 buf; sl@0: TInt aRemainingLen = aData.Length(); sl@0: TInt aHeaderLen = aHeader.Length(); sl@0: sl@0: __ASSERT_ALWAYS(iLoggerBody,User::Panic(KFloggerPanic, EInternalConsistencyFault)); sl@0: sl@0: if (aData.Length()==0) // nothing to do sl@0: { sl@0: return; sl@0: } sl@0: sl@0: sl@0: if (aHeaderLen > 0) sl@0: { sl@0: sl@0: if (aMargin.Length() == 0) sl@0: { sl@0: marginStr = HBufC8::New(aHeader.Length()); sl@0: if (marginStr == NULL) sl@0: { sl@0: return; // abort if No memory sl@0: } sl@0: TPtr8 marginStrPtr(marginStr->Des()); sl@0: marginStrPtr.AppendFill(' ',aHeader.Length()); sl@0: } sl@0: else sl@0: { sl@0: marginStr = aMargin.Alloc(); sl@0: } sl@0: } sl@0: sl@0: sl@0: sl@0: TUint blockStartPos = 0; sl@0: while (aRemainingLen>0) sl@0: { sl@0: TInt blockLength = (aRemainingLen>KHexDumpWidth ? KHexDumpWidth : aRemainingLen); sl@0: sl@0: // write the header/margin and print in hex which bytes we are about to write sl@0: if (blockStartPos == 0) sl@0: { sl@0: if (aHeaderLen > 0) sl@0: { sl@0: buf.Append(aHeader); sl@0: } sl@0: buf.AppendFormat(KFirstFormatString8,&(iLoggerBody->iFlogOverflow8), blockStartPos); sl@0: } sl@0: else sl@0: { sl@0: if (marginStr) sl@0: { sl@0: buf.Append(*marginStr); sl@0: } sl@0: buf.AppendFormat(KFirstFormatString8,&(iLoggerBody->iFlogOverflow8),blockStartPos); sl@0: } sl@0: sl@0: TInt bytePos; sl@0: // write the bytes as hex sl@0: for (bytePos = 0; bytePos < blockLength; bytePos++) sl@0: { sl@0: buf.AppendFormat(KSecondFormatString8,aData[blockStartPos + bytePos]); sl@0: } sl@0: while (bytePos++ < KHexDumpWidth) sl@0: { sl@0: buf.Append(KThreeSpaces8); sl@0: } sl@0: buf.Append(KTwoSpaces8); sl@0: // print the bytes as characters, or full stops if outside printable range sl@0: for (bytePos = 0; bytePos < blockLength; bytePos++) sl@0: { sl@0: buf.AppendFormat(KThirdFormatString8,(aData[blockStartPos + bytePos] < KLowestPrintableCharacter || aData[blockStartPos + bytePos] > KHighestPrintableCharacter) ? KFullStopChar8 : aData[blockStartPos + bytePos]); sl@0: } sl@0: sl@0: DoWrite(buf); sl@0: sl@0: buf.SetLength(0); sl@0: aRemainingLen -= blockLength; sl@0: blockStartPos += blockLength; sl@0: } sl@0: delete marginStr; sl@0: } sl@0: sl@0: sl@0: sl@0: EXPORT_C void ClientRunStubOrdinal1() sl@0: /** sl@0: * @removed This function has been removed because the flogsvrl dll contains the equivalent function sl@0: @internalComponent sl@0: */ sl@0: {User::Panic(KFloggerPanic, KErrNotSupported);} sl@0: