// SessionWriter.cpp
//
// Copyright (c) 2008 - 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 "SessionWriter.h"
#include "cliserv.h"
#include "CloggerServer.h"
CSession2* CSessionWriterServer::NewSessionL(const TVersion& /*aVersion*/, const RMessage2& /*aMessage*/) const
{
return new(ELeave) CSessionWriterSession();
}
CSessionWriterServer::CSessionWriterServer(CCloggerServer& aCloggerServer)
: CServer2(CActive::EPriorityHigh, ESharableSessions), iCloggerServer(aCloggerServer)
{
}
void CSessionWriterServer::ConstructL()
{
StartL(KSessionLogServer);
}
CSessionWriterServer& CSessionWriterSession::Server()
{
return *static_cast<CSessionWriterServer*>(const_cast<CServer2*>(CSession2::Server()));
}
void CSessionWriterSession::ServiceL(const RMessage2 &aMessage)
{
TInt res = KErrNone;
TBool handled = ETrue;
switch (aMessage.Function())
{
case ERegisterForLogMessages:
{
if (iSessionWriter)
{
// We're already registered
res = KErrAlreadyExists;
break;
}
CSessionWriter* writer = Server().CloggerServer().RegisterSessionWithSessionWriter(this);
if (!writer)
{
// Only one session can be registered at once, and some other session is
res = KErrInUse;
break;
}
iSessionWriter = writer;
RChunk& bufChunk = Server().CloggerServer().GetBufChunk();
aMessage.Complete(bufChunk);
return; // As we've handled it ourself
}
case EGetNextLog:
{
if (!iSessionWriterMessage.IsNull())
{
res = KErrAlreadyExists;
break;
}
if (!iSessionWriter)
{
PanicClient(aMessage, ENotRegisteredForLogs);
return;
}
iClientSharedChunkBase = (TAny*)aMessage.Ptr1();
iSessionWriter->SetEnabled(ETrue);
iSessionWriterMessage = aMessage;
if (iWaitingForClient)
{
iWaitingForClient = EFalse;
iSessionWriter->Completed();
}
return; // Don't want to complete this yet!
}
case ECancelGetNextLog:
if (iSessionWriter)
{
iSessionWriter->SetEnabled(EFalse);
}
if (!iSessionWriterMessage.IsNull())
{
iSessionWriterMessage.Complete(KErrCancel);
}
break;
default:
handled = EFalse;
}
if (handled)
{
aMessage.Complete(res);
}
else
{
PanicClient(aMessage, EPanicIllegalFunction);
}
}
void CSessionWriterSession::WriteBuffer(const TDesC8& aBuf)
{
const TUint8* ptr = aBuf.Ptr();
const TUint8* base = Server().CloggerServer().GetBufChunk().Base();
const TUint8* clientDataPtr = (const TUint8*)((TInt)iClientSharedChunkBase + (TInt)(ptr - base));
TPtrC8 clientPtr(clientDataPtr, aBuf.Length());
TPckg<TPtrC8> ptrBuf(clientPtr);
iWaitingForClient = ETrue;
TInt err = iSessionWriterMessage.Write(0, ptrBuf);
iSessionWriterMessage.Complete(err);
}
TBool CSessionWriterSession::WaitingForClient()
{
return iWaitingForClient;
}
CSessionWriterSession::~CSessionWriterSession()
{
if (iSessionWriter)
{
Server().CloggerServer().RegisterSessionWithSessionWriter(NULL);
}
}
//////////////////////////////
CSessionWriter::CSessionWriter(CCloggerServer& aServer)
: iServer(aServer)
{
}
void CSessionWriter::WriteBuf(TInt aBuf)
{
ASSERT(!IsBusyWriting() && iEnabled && iSession);
{
iBuf = aBuf;
const TDesC8& buf = iServer.GetBuf(aBuf);
iSession->WriteBuffer(buf);
}
}
TBool CSessionWriter::IsBusyWriting()
{
return iSession && iSession->WaitingForClient();
}
CSessionWriter::~CSessionWriter()
{
}
void CSessionWriter::CloseWriter()
{
delete this;
}
void CSessionWriter::SetEnabled(TBool aEnabled)
{
if (!iSession)
{
// If there's no session, we can't enable ourselves even if someone asks us to
aEnabled = EFalse;
}
iEnabled = aEnabled;
if (IsBusyWriting() && !aEnabled)
{
// Need to say we've completed this buffer
iServer.CompletedWritingBuf(this, iBuf);
}
}
void CSessionWriter::Completed()
{
iServer.CompletedWritingBuf(this, iBuf);
}