diff -r 000000000000 -r 307788aac0a8 realtimenetprots/sipfw/SIP/ConnectionMgr/src/TTCPMsgContentStart.cpp --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/realtimenetprots/sipfw/SIP/ConnectionMgr/src/TTCPMsgContentStart.cpp Tue Feb 02 01:03:15 2010 +0200 @@ -0,0 +1,191 @@ +// Copyright (c) 2004-2009 Nokia Corporation and/or its subsidiary(-ies). +// All rights reserved. +// This component and the accompanying materials are made available +// under the terms of "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: +// Nokia Corporation - initial contribution. +// +// Contributors: +// +// Description: +// Name : TTCPMsgContentStart.cpp +// Part of : ConnectionMgr +// Implementation +// Version : SIP/4.0 +// + + + +#include "TTCPMsgContentStart.h" +#include "sipmessage.h" +#include "SipAssert.h" +#include "MMsgAssemblerContext.h" +#include "MSigCompController.h" +#include "CSIPMsgAssembler.h" + + +// ---------------------------------------------------------------------------- +// TTCPMsgContentStart::DataReceivedL +// ---------------------------------------------------------------------------- +// +void TTCPMsgContentStart::DataReceivedL( TPtr8 aData, TUint& aNextLength ) + { + CSIPMessage* message = iMsgAssembler.Message(); + + // panic if message == 0 in debug mode. leaves in release mode. + __SIP_ASSERT_LEAVE( message, KErrGeneral ); + // panic if there is no content length in debug mode. + // leaves in release mode. + __SIP_ASSERT_LEAVE( message->HasAnnouncedContentLength(), + KErrGeneral ); + + TUint contentLen = message->AnnouncedContentLength(); + + // panic if content length <= 0 in debug mode. + // leaves in release mode. + __SIP_ASSERT_LEAVE( contentLen > 0, KErrGeneral ); + + // if message contains already some content, received data is complementing + // it. this kind of situation might occur when sigcomp splits too big sip + // message to pieces + if ( message->Content().Length() > 0 ) + { + iMsgAssembler.MsgBuffer().InsertL( iMsgAssembler.MsgBuffer().Size(), + message->Content() ); + iMsgAssembler.MsgBuffer().Compress(); + + // remove old uncomplete content + HBufC8* uncompletedContent = message->TakeContentOwnershipL(); + delete uncompletedContent; + } + + if ( iMsgAssembler.SigComp().IsSupported() && + iMsgAssembler.IsSigComp() && + HandleComplementingSigCompDataL( aData, aNextLength, contentLen ) ) + { + return; + } + + if ( iMsgAssembler.MsgBuffer().Size() > 0 ) + { + // insert received data to msg buffer. + iMsgAssembler.MsgBuffer().InsertL( + iMsgAssembler.MsgBuffer().Size(), aData ); + iMsgAssembler.MsgBuffer().Compress(); + // delete the content of received data + aData.Delete( 0, aData.Length() ); + + TPtr8 bufPtr = iMsgAssembler.MsgBuffer().Ptr( 0 ); + + // check if the msg buffer contains the whole content, if so + // copy the msg buffer to new data buffer, clean the msg buffer + // and enter to msg content end state. + if ( contentLen <= static_cast< TUint >( bufPtr.Length() ) ) + { + HBufC8* newData = HBufC8::NewLC( bufPtr.Length() ); + // copy the msg buffer data new data + TPtr8 newDataPtr = newData->Des(); + // delete the content of received data + aData.Delete( 0, aData.Length() ); + newDataPtr.Append(iMsgAssembler.MsgBuffer().Ptr(0)); + // clean the msg buffer + iMsgAssembler.MsgBuffer().Reset(); + iMsgAssembler.MsgBuffer().Compress(); + + iMsgAssembler.ChangeState( MMsgAssemblerContext::EMsgContentEnd ); + iMsgAssembler.CurrentState().DataReceivedL( newDataPtr, + aNextLength ); + CleanupStack::PopAndDestroy( newData ); + } + // if the msg buffer contains not enough content, ask the next + // length to be received. + else + { + aNextLength = contentLen - aData.Length(); + } + } + else if ( contentLen <= static_cast< TUint >( aData.Length() ) ) + { + iMsgAssembler.ChangeState(MMsgAssemblerContext::EMsgContentEnd); + iMsgAssembler.CurrentState().DataReceivedL( aData, aNextLength ); + } + else + { + iMsgAssembler.MsgBuffer().InsertL( + iMsgAssembler.MsgBuffer().Size(), aData ); + iMsgAssembler.MsgBuffer().Compress(); + aNextLength = contentLen - aData.Length(); + } + } + +// ---------------------------------------------------------------------------- +// TTCPMsgContentStart::HandleComplementingSigCompDataL +// ---------------------------------------------------------------------------- +// +TBool TTCPMsgContentStart::HandleComplementingSigCompDataL( + TPtr8 aData, + TUint& aNextLength, + TInt aAnnouncedContentLen ) + { + // If still receiving compressed data, current contents have to be + // stored until we come back from comp states, in sigcomp point of + // view message can be complete but it ain't necessary complete + // in sip point of view. All data in aData or msgbuffer are not + // necessarily decompressed - these have to be taken with us when + // going back to decompression states + + TInt unconsumedBytes( iMsgAssembler.UnConsumedBytes() ); + + TPtr8 msgBufPtr( iMsgAssembler.MsgBuffer().Ptr( 0 ) ); + HBufC8* content = NULL; + + TInt decompressedDataLen = aData.Length() - unconsumedBytes; + + __SIP_ASSERT_LEAVE( decompressedDataLen > 0, KErrGeneral ); + + TInt msgBufLen( msgBufPtr.Length() ); + TInt decompressedLen( msgBufLen + decompressedDataLen ); + if ( aAnnouncedContentLen <= decompressedLen ) + { + // Enough decompressed content data + return EFalse; + } + + // Store decompressed data to message content + if ( msgBufLen > 0 ) + { + content = HBufC8::NewL( decompressedLen ); + TPtr8 contentPtr( content->Des() ); + contentPtr.Copy( msgBufPtr ); + contentPtr.Append( aData.Left( decompressedDataLen ) ); + } + else + { + content = aData.Left( decompressedDataLen ).AllocL(); + } + + // Remove decompressed data which was stored to content + aData.Delete( 0, decompressedDataLen ); + + // Clean msgbuffer + iMsgAssembler.MsgBuffer().Reset(); + iMsgAssembler.MsgBuffer().Compress(); + + iMsgAssembler.SetUnConsumedBytes( 0 ); + + CSIPMessage* message = iMsgAssembler.Message(); + message->SetContent( content ); // ownership is transferred + content = NULL; + + aNextLength = CSIPMsgAssembler::EMsgBufferSize; + + iMsgAssembler.ChangeState( MMsgAssemblerContext::ECompMsgStart ); + iMsgAssembler.CurrentState().DataReceivedL( aData, aNextLength ); + + return ETrue; + } + +// End of File