diff -r 000000000000 -r 7f656887cf89 libraries/clogger/src/CloggerClient.cpp --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/libraries/clogger/src/CloggerClient.cpp Wed Jun 23 15:52:26 2010 +0100 @@ -0,0 +1,822 @@ +// CloggerClient.cpp +// +// Copyright (c) 2006 - 2010 Accenture. All rights reserved. +// This component and the accompanying materials are made available +// under the terms of the "Eclipse Public License v1.0" +// which accompanies this distribution, and is available +// at the URL "http://www.eclipse.org/legal/epl-v10.html". +// +// Initial Contributors: +// Accenture - Initial contribution +// + +#include "clogger.h" +#include "cliserv.h" +#include "SensibleClient_Internals.h" +#include "common.h" +#include +#include +#include + +#define KFlagsMask 0x0FFFFFFF +#define KTestTagEnabled 0x10000000 +#define KNoLogMask 0x80000000 // This is the log mask used internally if you call an overload which doesn't specify one + +#define iBody (*reinterpret_cast(&iPimpl)) + +#ifndef PERFORMANCE_CRITICAL + +// declares RClogger* clogger +#define CheckConnected() \ + RClogger _cloggerHandle; \ + RClogger* clogger = &_cloggerHandle; \ + GetTls(clogger, ETrue); \ + if (!clogger) return + +#define GetTlsOrConnect(aTag) \ + RClogger _cloggerHandle; \ + RClogger* clogger = &_cloggerHandle; \ + TInt err; \ + TBool isHandle = GetTls(clogger, ETrue, &aTag, &err) + +#define GetTlsOrNull() \ + RClogger _cloggerHandle; \ + RClogger* clogger = &_cloggerHandle; \ + TBool isHandle = GetTls(clogger, EFalse) + +TBool RClogger::GetTls(RClogger*& aClogger, TBool aAutoConnect, const TDesC* aTag, TInt* aError) + { + TAny* tls = Dll::Tls(); + if ((TUint)tls & 1) + { + // Then it's a handle + aClogger->SetHandle((TInt)((TUint)tls >> 1)); + return ETrue; + } + else if (tls) + { + // Then it's a pointer + aClogger = (RClogger*)tls; + return EFalse; + } + else if (aAutoConnect) + { + TInt err = aClogger->Connect(aTag ? *aTag : KNullDesC); + aClogger->iFlags &= ~EUseHeapBuffer; // Don't (by default) use a buffer for static connections because we can't track it without upgrading TLS + if (err) + { + if (aError) *aError = err; + aClogger = NULL; + return ETrue; + } + __ASSERT_DEBUG((aClogger->Handle() & 0x80000000) == 0, User::Panic(_L("HandleTooBig"), 0)); + + err = Dll::SetTls((TAny*) ((aClogger->Handle() << 1) | 1)); + if (err) + { + aClogger->Close(); + if (aError) *aError = err; + aClogger = NULL; + } + return ETrue; + } + else + { + aClogger = NULL; + return ETrue; + } + } + +#endif // PERFORMANCE_CRITICAL + +NONSHARABLE_CLASS(RCloggerBody) : public RSensibleSessionBody + { +public: + RCloggerBody(RClogger& aSession); + TInt DoCreateSession(const TDesC &aServer, const TVersion &aVersion, TInt aAsyncMessageSlots); + TInt DoSendReceive(TInt aFunction, const TIpcArgs &aArgs) const; + void DoSendReceive(TInt aFunction, const TIpcArgs &aArgs, TRequestStatus& aStatus) const; + void ServerDiedL(); + void DispatchCallbackL(TServerCallback& aCallback, TCallbackParser& aParser); + +private: + friend class RClogger; + //RClogger& iSession; // No need to store this, we can calculate it from our this pointer since we know we are always embedded in an RClogger + }; + +#define iSession (*(RClogger*)((TUint8*)this - _FOFF(RClogger, iPimpl))) + +RCloggerBody::RCloggerBody(RClogger& /*aSession*/) + : RSensibleSessionBody() //, iSession(aSession) + {} + +TInt RCloggerBody::DoCreateSession(const TDesC &aServer, const TVersion &aVersion, TInt aAsyncMessageSlots) + { + return iSession.CreateSession(aServer, aVersion, aAsyncMessageSlots); + } + +TInt RCloggerBody::DoSendReceive(TInt aFunction, const TIpcArgs &aArgs) const + { + return iSession.SendReceive(aFunction, aArgs); + } + +void RCloggerBody::DoSendReceive(TInt aFunction, const TIpcArgs &aArgs, TRequestStatus& aStatus) const + { + iSession.SendReceive(aFunction, aArgs, aStatus); + } + +EXPORT_C RClogger::RClogger() + : iFlags(0), iEnabled(EAllEnabled), iBuf(), iSequence(0) + { + __ASSERT_COMPILE(sizeof(iPimpl) >= sizeof(RCloggerBody)); + __ASSERT_COMPILE(sizeof(RClogger) == 10*4); // This is the size we've published, it CANNOT change + + // Initialise the body using placement new + new(iPimpl) RCloggerBody(*this); + } + +EXPORT_C RClogger::RClogger(TAny* aTls) + : iFlags(0), iEnabled(EAllEnabled), iBuf(), iSequence(0) + { + // This overload is only ever supposed to be used by the TlsLog inline functions, hence why it's private but still + // exported. + new(iPimpl) RCloggerBody(*this); + SetHandle(reinterpret_cast(aTls)); + } + +EXPORT_C TInt RClogger::Connect() + { + return Connect(KNullDesC); + } + +EXPORT_C TInt RClogger::Connect(const TDesC& aTag) + { + iFlags |= EUseHeapBuffer; // Set by default + + TInt err = iBody.Connect(1, EFalse); // Only need 1 slot as we only have one async function (which is hidden within RSensibleSession) + if (!err) + { + err = ShareAuto(); + } + if (!err) + { + TPckg enabledPkg(iEnabled); + TInt res = SendReceive(ESetTag, TIpcArgs(&aTag, NULL, &enabledPkg)); + if (res >= 0) + { + iSequence = res; + } + else + { + err = res; + } + } + if (err) + { + Close(); + } + return err; + } + +EXPORT_C TInt RClogger::StaticConnect() + { + return StaticConnect(KNullDesC); + } + +#ifndef PERFORMANCE_CRITICAL + +EXPORT_C TInt RClogger::StaticConnect(const TDesC& aTag) + { + GetTlsOrConnect(aTag); + if (clogger) return KErrNone; + else return err; + } + +EXPORT_C void RClogger::StaticClose() + { + GetTlsOrNull(); + if (clogger) + { + clogger->Close(); + if (!isHandle) + { + delete clogger; + } + Dll::SetTls(NULL); + Dll::FreeTls(); + } + } + +#endif // PERFORMANCE_CRITICAL + + +EXPORT_C void RClogger::Log(TRefByValue aFmt, ...) + { + VA_LIST args; + VA_START(args, aFmt); + LogList(KNoLogMask, aFmt, args); + VA_END(args); + } + +EXPORT_C void RClogger::Log(TUint32 aLogMask, TRefByValue aFmt, ...) + { + VA_LIST args; + VA_START(args, aFmt); + LogList(aLogMask, aFmt, args); + VA_END(args); + } + +EXPORT_C void RClogger::Log(TRefByValue aFmt, ...) + { + VA_LIST args; + VA_START(args, aFmt); + LogList(KNoLogMask, aFmt, args); + VA_END(args); + } + +EXPORT_C void RClogger::Log(TUint32 aLogMask, TRefByValue aFmt, ...) + { + VA_LIST args; + VA_START(args, aFmt); + LogList(aLogMask, aFmt, args); + VA_END(args); + } + +EXPORT_C void RClogger::Log(const char* aFmt, ...) + { + VA_LIST args; + VA_START(args, aFmt); + LogList(KNoLogMask, aFmt, args); + VA_END(args); + } + +EXPORT_C void RClogger::Log(TUint32 aLogMask, const char* aFmt, ...) + { + VA_LIST args; + VA_START(args, aFmt); + LogList(aLogMask, aFmt, args); + VA_END(args); + } + +EXPORT_C void RClogger::LogList(TRefByValue aFmt, VA_LIST aList) + { + LogList(KNoLogMask, aFmt, aList); + } + +EXPORT_C void RClogger::LogList(TUint32 aLogMask, TRefByValue aFmt, VA_LIST aList) + { + if (!Enabled(aLogMask)) return; + TUint32 tickCount = User::NTickCount(); + + TPtrC fmt(aFmt); + if (iFlags & ETrimTrailingNewlines) + { + TInt len = fmt.Length(); + if (len && fmt[len-1] == '\n') fmt.Set(fmt.Left(len-1)); + len = fmt.Length(); + if (len && fmt[len-1] == '\r') fmt.Set(fmt.Left(len-1)); + } + #define SF_FORMAT fmt + #define SF_LIST aList + #define SF_BUF iBuf + #define SF_ACTION(buf) SendReceive(ELog8, TIpcArgs(&buf, tickCount, aLogMask)) + #define SF_WIDE + #define SF_STACKONLY (!(iFlags & EUseHeapBuffer)) + #include "SensibleFormat.h" + + //if (!(iFlags&ECacheClientBuffers)) iBuf.Close(); + } + +EXPORT_C void RClogger::LogList(TRefByValue aFmt, VA_LIST aList) + { + LogList(KNoLogMask, aFmt, aList); + } + +EXPORT_C void RClogger::LogList(TUint32 aLogMask, TRefByValue aFmt, VA_LIST aList) + { + if (!Enabled(aLogMask)) return; + TUint32 tickCount = User::NTickCount(); + + TPtrC8 fmt(aFmt); + if (iFlags & ETrimTrailingNewlines) + { + TInt len = fmt.Length(); + if (len && fmt[len-1] == '\n') fmt.Set(fmt.Left(len-1)); + len = fmt.Length(); + if (len && fmt[len-1] == '\r') fmt.Set(fmt.Left(len-1)); + } + #define SF_FORMAT fmt + #define SF_LIST aList + #define SF_BUF iBuf + #define SF_ACTION(buf) SendReceive(ELog8, TIpcArgs(&buf, tickCount, aLogMask)) + #define SF_STACKONLY (!(iFlags & EUseHeapBuffer)) + #include "SensibleFormat.h" + + //if (!(iFlags&ECacheClientBuffers)) iBuf.Close(); + } + +EXPORT_C void RClogger::LogList(const char* aFmt, VA_LIST aList) + { + TPtrC8 ptr((const TUint8*)aFmt); + LogList(KNoLogMask, ptr, aList); + } + +EXPORT_C void RClogger::LogList(TUint32 aLogMask, const char* aFmt, VA_LIST aList) + { + TPtrC8 ptr((const TUint8*)aFmt); + LogList(aLogMask, ptr, aList); + } + +#ifndef PERFORMANCE_CRITICAL + +EXPORT_C void RClogger::Slog(TUint32 aLogMask, TRefByValue aFmt, ...) + { + CheckConnected(); + VA_LIST args; + VA_START(args, aFmt); + clogger->LogList(aLogMask, aFmt, args); + VA_END(args); + } + +EXPORT_C void RClogger::Slog(TUint32 aLogMask, TRefByValue aFmt, ...) + { + CheckConnected(); + VA_LIST args; + VA_START(args, aFmt); + clogger->LogList(aLogMask, aFmt, args); + VA_END(args); + } + +EXPORT_C void RClogger::Slog(TUint32 aLogMask, const char* aFmt, ...) + { + CheckConnected(); + VA_LIST args; + VA_START(args, aFmt); + clogger->LogList(aLogMask, aFmt, args); + VA_END(args); + } + +EXPORT_C void RClogger::Slog(TRefByValue aFmt, ...) + { + CheckConnected(); + VA_LIST args; + VA_START(args, aFmt); + clogger->LogList(KNoLogMask, aFmt, args); + VA_END(args); + } + +EXPORT_C void RClogger::Slog(TRefByValue aFmt, ...) + { + CheckConnected(); + VA_LIST args; + VA_START(args, aFmt); + clogger->LogList(KNoLogMask, aFmt, args); + VA_END(args); + } + +EXPORT_C void RClogger::Slog(const char* aFmt, ...) + { + CheckConnected(); + VA_LIST args; + VA_START(args, aFmt); + clogger->LogList(KNoLogMask, aFmt, args); + VA_END(args); + } + +EXPORT_C void RClogger::SlogList(TUint32 aLogMask, TRefByValue aFmt, VA_LIST aList) + { + CheckConnected(); + clogger->LogList(aLogMask, aFmt, aList); + } + +EXPORT_C void RClogger::SlogList(TUint32 aLogMask, TRefByValue aFmt, VA_LIST aList) + { + CheckConnected(); + clogger->LogList(aLogMask, aFmt, aList); + } + +EXPORT_C void RClogger::SlogList(TUint32 aLogMask, const char* aFmt, VA_LIST aList) + { + CheckConnected(); + clogger->LogList(aLogMask, aFmt, aList); + } + +EXPORT_C void RClogger::SlogList(TRefByValue aFmt, VA_LIST aList) + { + CheckConnected(); + clogger->LogList(KNoLogMask, aFmt, aList); + } + +EXPORT_C void RClogger::SlogList(TRefByValue aFmt, VA_LIST aList) + { + CheckConnected(); + clogger->LogList(KNoLogMask, aFmt, aList); + } + +EXPORT_C void RClogger::SlogList(const char* aFmt, VA_LIST aList) + { + CheckConnected(); + clogger->LogList(KNoLogMask, aFmt, aList); + } + +EXPORT_C void RClogger::SetStaticLogBehaviour(TUint aLogBehaviour) + { + GetTlsOrConnect(KNullDesC); + if (isHandle && (aLogBehaviour != 0)) + { + // Then we need to upgrade from handle to pointer + TInt err = KErrNoMemory; + RClogger* ptr = new RClogger(); + if (ptr) + { + ptr->SetHandle(clogger->Handle()); + err = Dll::SetTls(ptr); + if (err) delete ptr; + } + if (err) + { + // Then log it. + _LIT(KErr, "RClogger couldn't upgrade handle to pointer, err %i"); + clogger->Log(KErr(), err); + + aLogBehaviour = 0; // Don't update flags if we failed to honour them + } + else + { + clogger = ptr; + } + } + + clogger->SetLogBehaviour(aLogBehaviour); + } + +#endif // PERFORMANCE_CRITICAL + +EXPORT_C void RClogger::SetLogBehaviour(TUint aLogBehaviour) + { + iFlags = (iFlags & ~KFlagsMask) | (aLogBehaviour & KFlagsMask); + + if (!(iFlags & EUseHeapBuffer)) iBuf.Close(); + + /* This is not needed any more + if (iFlags & EMonitorTagState) + { + iBody.StartCallbackDispatcher(); + } + else + { + iBody.StopCallbackDispatcher(); + } + */ + } + +EXPORT_C TInt RClogger::SetEnabled(const TDesC& aTag, TUint32 aEnabledMask) + { + return SendReceive(ESetEnabled, TIpcArgs(&aTag, aEnabledMask)); + } + +EXPORT_C TUint32 RClogger::IsEnabled(const TDesC& aTag) + { + TPckgBuf logMask; + TInt res = SendReceive(EIsEnabled, TIpcArgs(&aTag, &logMask)); + return res < 0 ? EFalse : logMask(); + } + +/* +EXPORT_C void RClogger::TailLogFile(TInt aNumberOfChars) + { + SendReceive(ETailLogToRDebug, TIpcArgs(aNumberOfChars)); + } + +EXPORT_C void RClogger::TailLogFile(TDes8& aBuf) + { + SendReceive(ETailLogToBuf, TIpcArgs(&aBuf)); + } +*/ + +EXPORT_C void RClogger::SetGlobalOptions(TUint aGlobalOptions) + { + SendReceive(ESetGlobalOptions, TIpcArgs(aGlobalOptions)); + } + +EXPORT_C TUint RClogger::GetGlobalOptions() + { + return SendReceive(EGetGlobalOptions, TIpcArgs()); + } + +EXPORT_C TInt RClogger::GetRamBufferSize(TInt* aNumberOfBuffers) + { + TBuf8<8> buf; + buf.SetLength(8); + SendReceive(EGetRamBufferSize, TIpcArgs(&buf)); + TInt* ptr = (TInt*)buf.Ptr(); + TInt size = ptr[0]; + if (aNumberOfBuffers) + { + *aNumberOfBuffers = ptr[1]; + } + return size; + } + +EXPORT_C void RClogger::SetRamBufferSize(TInt aSize, TInt aNum) + { + SendReceive(ESetRamBufferSize, TIpcArgs(aSize, aNum)); + } + +EXPORT_C TInt RClogger::Rotate() + { + return SendReceive(ERotate, TIpcArgs()); + } + +EXPORT_C TInt RClogger::Rotate(TDes& aFileName) + { + aFileName.Zero(); + return SendReceive(ERotate, TIpcArgs(&aFileName)); + } + +EXPORT_C void RClogger::SetRotateBehaviour(TInt aNumberOfOldLogsToKeep, TUint aRotateBehaviour) + { + SendReceive(ESetRotateBehaviour, TIpcArgs(aNumberOfOldLogsToKeep, aRotateBehaviour)); + } + +EXPORT_C TUint RClogger::GetRotateBehaviour(TInt* aNumberOfOldLogsToKeep) + { + TBuf8<8> buf; + buf.SetLength(8); + SendReceive(EGetRotateBehaviour, TIpcArgs(&buf)); + TInt* ptr = (TInt*)buf.Ptr(); + TUint behav = ptr[0]; + if (aNumberOfOldLogsToKeep) + { + *aNumberOfOldLogsToKeep = ptr[1]; + } + return behav; + } + +EXPORT_C void RClogger::PersistSettings() + { + SendReceive(EPersistSettings, TIpcArgs()); + } + +EXPORT_C void RClogger::ResetSettings() + { + SendReceive(EResetSettings, TIpcArgs()); + } + +EXPORT_C void RClogger::Close() + { + iBuf.Close(); + iBody.Close(); + RSessionBase::Close(); + } + +void RCloggerBody::DispatchCallbackL(TServerCallback& aCallback, TCallbackParser& aParser) + { + switch (aCallback.iCode) + { + case ETagEnabledChanged: + { + iSession.iEnabled = aParser.NextUint(); + + /* + if (iSession.iFlags & KTestTagEnabled) + { + iSession.iFlags &= ~KTestTagEnabled; + CActiveScheduler::Stop(); + } + */ + break; + } + } + } + +void RCloggerBody::ServerDiedL() + { + } + +EXPORT_C void RClogger::GetTagStatesL(CDesCArray*& aTagNames, RBuf8& aEnabled) + { + aTagNames = NULL; + aEnabled.Close(); + + TServerCallback cb; + TPckg cbPkg(cb); + User::LeaveIfError(SendReceive(EGetTagStates1, TIpcArgs(&cbPkg))); + + RBuf8 context; + CleanupClosePushL(context); + if (cb.iContextLength) + { + context.CreateL(cb.iContextLength); + User::LeaveIfError(SendReceive(EGetTagStates2, TIpcArgs(&context))); + } + TCallbackParser parser(cb); + parser.SetContext(context); + + TPtrC8 enabledBuf = parser.NextDesC8(); + TInt numTags = enabledBuf.Length() / 4; // 32 bits per tag + + CDesCArrayFlat* tags = new(ELeave) CDesCArrayFlat(numTags); + CleanupStack::PushL(tags); + while (numTags--) + { + tags->AppendL(parser.NextDesC()); + } + + aEnabled.CreateL(enabledBuf); + CleanupStack::Pop(tags); + CleanupStack::PopAndDestroy(&context); + aTagNames = tags; + } + +EXPORT_C void RClogger::SetTagStatesL(const CDesCArray* aTagNames, const TDesC8& aEnabled) + { + __ASSERT_ALWAYS(aTagNames, User::Leave(KErrArgument)); + TInt count = aTagNames->MdcaCount(); + __ASSERT_ALWAYS(count * 4 == aEnabled.Size(), User::Leave(KErrArgument)); // Number of tags must equal the number of 4-byte entries in aEnabled + + CBufFlat* buf = CBufFlat::NewL(4096); + CleanupStack::PushL(buf); + RBufWriteStream stream(*buf); + CleanupClosePushL(stream); + stream.WriteInt32L(count); + //stream.WriteL(aEnabled); + stream << aEnabled; + for (TInt i = 0; i < count; i++) + { + const TPtrC name = aTagNames->MdcaPoint(i); + stream << name; + } + CleanupStack::PopAndDestroy(&stream); // Calls close, flushes buffer (probably not necessary with a RBufWriteStream) + TPtrC8 bufPtr = buf->Ptr(0); + User::LeaveIfError(SendReceive(ESetTagStates, TIpcArgs(&bufPtr))); + CleanupStack::PopAndDestroy(buf); + } + +EXPORT_C TInt RClogger::Reserved(TInt aCode, TAny*& aArg, TAny* aArg2) + { + TInt res = KErrNone; + if (aCode == 0xF10C10) + { + res = iBody.Connect(2, EFalse); // Used by flogger shim to access internals of clogger that would otherwise be hidden to it + } + else if (aCode == 0xC0FFEE) + { + RChunk*& chunk = reinterpret_cast(aArg); + TInt size = reinterpret_cast(aArg2); + res = SendReceive(ECreatePerformanceLoggingChunk, TIpcArgs(size)); + if (res > 0) + { + chunk->SetHandle(res); + res = KErrNone; + } + if (res == KErrNotSupported) + { + // Getting the chunk from the server is only possible if the debug router LDD is included, because there's no API + // to pass a chunk from a server to a client (without doing it kernel side). So if the LDD isn't present, we need + // to fall back to constructing it on our side and passing it to the server. + res = chunk->CreateGlobal(KNullDesC, size, size); + if (res == KErrNone) + { + res = SendReceive(ERegisterPerformanceLoggingChunk, TIpcArgs(*chunk)); + } + } + } + else if (aCode == 0x5e55) + { + res = SendReceive(EStartSessionWriterServer); + } + else + { + User::Panic(_L("CloggerClient"), 0); + } + return res; + } + +EXPORT_C TInt RClogger::StaticReserved(TInt aCode, TAny*& aArg, TAny* aArg2) + { + TInt res = KErrNone; + if (aCode == 0xD0715) + { + RClogger clogger; + res = clogger.Connect(*reinterpret_cast(aArg2)); + if (res == KErrNone) + { + aArg = reinterpret_cast(clogger.Handle()); + } + } + else + { + User::Panic(_L("CloggerClient"), 0); + } + return res; + } + +EXPORT_C void RClogger::HexDump(TUint32 aLogMask, const TDesC8& aHeader, const TDesC8& aData) + { + if (!(iEnabled & aLogMask)) return; + + SendReceive(EHexDump, TIpcArgs(&aHeader, &aData, User::NTickCount(), aLogMask)); + } + +EXPORT_C void RClogger::HexDump(const TDesC8& aHeader, const TDesC8& aData) + { + HexDump(KNoLogMask, aHeader, aData); + } + +#ifndef PERFORMANCE_CRITICAL + +EXPORT_C void RClogger::StaticHexDump(TUint32 aLogMask, const TDesC8& aHeader, const TDesC8& aData) + { + CheckConnected(); + clogger->HexDump(aLogMask, aHeader, aData); + } + +EXPORT_C void RClogger::StaticHexDump(const TDesC8& aHeader, const TDesC8& aData) + { + CheckConnected(); + clogger->HexDump(KNoLogMask, aHeader, aData); + } + +#endif // PERFORMANCE_CRITICAL + +inline TBool RClogger::Enabled(TUint32 aMask) + { + // First check if anything's changed + TInt seq = 0; + TInt err = RProperty::Get(KCloggerUid, ESequenceNumber, seq); + if (err == KErrNone && seq > iSequence) + { + UpdateEnabled(seq); + } + + if (!(iEnabled & aMask)) return EFalse; + + return ETrue; + } + +void RClogger::UpdateEnabled(TInt aSequence) + { + iSequence = aSequence; + TPckg buf(iEnabled); + SendReceive(EUpdateEnabledMask, TIpcArgs(&buf)); + iFlags &= ~KTestTagEnabled; + } + +EXPORT_C RCloggerLogConsumer::RCloggerLogConsumer() + : iResultBufferPtr(NULL, 0) + { + } + +EXPORT_C TInt RCloggerLogConsumer::Connect() + { + RClogger clogger; + TInt res = clogger.Connect(); + if (res) return res; + + TAny* arg1 = NULL; + res = clogger.Reserved(0x5E55, arg1, NULL); // This requests clogger to start the session writer server + clogger.Close(); + if (res != KErrNone && res != KErrAlreadyExists) + { + return res; + } + + res = CreateSession(KSessionLogServer, TVersion(0,0,0), 2); + if (res) return res; + + res = SendReceive(ERegisterForLogMessages); + if (res < 0) return res; + iSharedChunk.SetHandle(res); + return KErrNone; + } + +EXPORT_C void RCloggerLogConsumer::GetNextLog(TRequestStatus& aStatus, TPtrC8& aResultBuffer) + { + // Server will update aResultBuffer to point to the appropriate location in iSharedChunk. + // It can do this because we pass in effectively TPckg(aResultBuffer) and tell the server + // what the shared chunk's Base address is in our address space. The server then computes what + // aResultBuffer should look like and writes it back + iResultBufferPtr.Set((TUint8*)&aResultBuffer, sizeof(TPtrC8), sizeof(TPtrC8)); + SendReceive(EGetNextLog, TIpcArgs(&iResultBufferPtr, iSharedChunk.Base()), aStatus); + } + +EXPORT_C void RCloggerLogConsumer::CancelGetNextLog() + { + SendReceive(ECancelGetNextLog); + } + +EXPORT_C void RCloggerLogConsumer::Close() + { + iSharedChunk.Close(); + RSessionBase::Close(); + } + +EXPORT_C void Clogger_Slog(const char* aFmt, ...) + { + VA_LIST list; + VA_START(list, aFmt); + TPtrC8 fmt((const TUint8*)aFmt); + RClogger::SlogList(fmt, list); + VA_END(list); + }