diff -r 000000000000 -r f5a58ecadc66 upnp/upnpstack/dlnawebserver/src/upnphttpchunkparser.cpp --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/upnp/upnpstack/dlnawebserver/src/upnphttpchunkparser.cpp Tue Feb 02 01:12:20 2010 +0200 @@ -0,0 +1,412 @@ +/** @file +* Copyright (c) 2005-2006 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: Declares chunk parsing class. +* +*/ + + +// INCLUDE FILES +#include "upnphttpchunkparser.h" +#include "upnpcons.h" + + +// CONSTANTS + +// ============================ MEMBER FUNCTIONS =============================== + +// ----------------------------------------------------------------------------- +// CUpnpHttpChunkParser::NewL +// Two-phased constructor +// ----------------------------------------------------------------------------- +// +CUpnpHttpChunkParser* CUpnpHttpChunkParser::NewL() + { + + CUpnpHttpChunkParser* self = new (ELeave) CUpnpHttpChunkParser(); + CleanupStack::PushL( self ); + self->ConstructL(); + CleanupStack::Pop( self ); + + return self; + } + +// ----------------------------------------------------------------------------- +// CUpnpHttpChunkParser::~CUpnpHttpChunkParser +// C++ default destructor +// ----------------------------------------------------------------------------- +// +CUpnpHttpChunkParser::~CUpnpHttpChunkParser() + { + } + +// ----------------------------------------------------------------------------- +// CUpnpHttpChunkParser::CUpnpHttpChunkParser +// C++ default constructor +// ----------------------------------------------------------------------------- +// +CUpnpHttpChunkParser::CUpnpHttpChunkParser() +:iContext(EUnknown), + iChunkSize(KErrNotFound), + iError (KErrNone) + { + } + +// ----------------------------------------------------------------------------- +// CUpnpHttpChunkParser::ConstructL +// Two-phased constructor +// ----------------------------------------------------------------------------- +// +void CUpnpHttpChunkParser::ConstructL() + { + } + +// ----------------------------------------------------------------------------- +// CUpnpHttpChunkParser::Reset +// Checks if decoding ended +// ----------------------------------------------------------------------------- +// +void CUpnpHttpChunkParser::Reset() + { + iContext = EUnknown; + iError = KErrNone; + iChunkSize = KErrNotFound; + } + +// ----------------------------------------------------------------------------- +// CUpnpHttpChunkParser::SetErrorState +// ----------------------------------------------------------------------------- +// +void CUpnpHttpChunkParser::SetErrorState() + { + iError = EHttpRequestTimeout; + iContext = EError; + } + +// ----------------------------------------------------------------------------- +// CUpnpHttpChunkParser::Parse +// Decoding the chunked-encoded buffer +// ----------------------------------------------------------------------------- +// +TInt CUpnpHttpChunkParser::Parse(TDes8& aBuffer, TInt& aPos) + { + TBool interrupt = EFalse; + while(!interrupt) + { + switch(iContext) + { + case EUnknown: + iContext = EHeader; + case EHeader: + interrupt = ParseHeader(aBuffer,aPos); + break; + case ELastChunk: + interrupt = ParseLastChunk(aBuffer,aPos); + break; + case EBody: + interrupt = ParseBody(aBuffer,aPos); + break; + case EEndChunkBody: + iContext = EHeader; + break; + case EExtension: + interrupt = ParseExtension(aBuffer,aPos); + break; + case ETrailer: + interrupt = ParseTrailer(aBuffer,aPos); + break; + case EError: + return iError; + case EFinish: + return KErrNone; + default: + return KErrUnknown; + } + } + return KErrNone; + } +// ----------------------------------------------------------------------------- +// CUpnpHttpChunkParser::ParseL +// Decoding the chunked-encoded buffer +// ----------------------------------------------------------------------------- +// +TBool CUpnpHttpChunkParser::ParseBody( TDes8& aBuffer, TInt& aPos ) + { + if ( IsEmpty( aBuffer, aPos ) ) + { + return ETrue; + } + + TPtrC8 pointer( aBuffer.Right( aBuffer.Length() - aPos ) ); + + if ( iBytesAppended + pointer.Length() >= iChunkSize ) + { + aPos += ( iChunkSize - iBytesAppended ); + pointer.Set( aBuffer.Right( aBuffer.Length() - aPos ) ); + TInt lineFeed = pointer.FindF(UpnpString::KLineFeed()); + //linefeed found + if ( !lineFeed ) + { + aBuffer.Delete( aPos, UpnpString::KLineFeed().Length() ); + iContext = EEndChunkBody; + return ( aPos == aBuffer.Length() ); + } + //linefeed not found, end of buffer + else if ( lineFeed == KErrNotFound && + ( ( aPos + UpnpString::KLineFeed().Length() ) > aBuffer.Length() ) + ) + { + iBytesAppended = iChunkSize; + return ETrue; + } + //size doesn't comply with the header value + iError = KErrGeneral; + iContext = EError; + return EFalse; + } + else + { + iBytesAppended += pointer.Length(); + aPos = aBuffer.Length(); + return ETrue; + } + } +// ----------------------------------------------------------------------------- +// CUpnpHttpChunkParser::ParseL +// Decoding the chunked-encoded buffer +// ----------------------------------------------------------------------------- +// +TBool CUpnpHttpChunkParser::ParseHeader( TDes8& aBuffer, TInt& aPos ) + { + if ( IsEmpty( aBuffer, aPos ) ) + { + return ETrue; + } + iChunkSize = KErrNotFound; + iBytesAppended = 0; + TPtrC8 pointer(NULL,0); + //if '\r\n' exists + TInt lineFeed = aBuffer.Right( aBuffer.Length() - aPos ).FindF( UpnpString::KLineFeed ); + //if ';' exists + TInt semiColon = aBuffer.Right( aBuffer.Length() - aPos ).FindF( UpnpString::KSemiColon ); + //semicolon ignored if occurs after the linefeed + if ( semiColon !=KErrNotFound && lineFeed !=KErrNotFound && lineFeed KMaxTInt ) + { + //size too big + iError = ( error ) ? error: EHttpInsufficientStorage; + iContext = EError; + return EFalse; + } + } + + aBuffer.Delete( aPos,len ); + return ETrue; + } + + //get size + TInt error = lex.Val( size, EHex ); + if ( error!= KErrNone || size > KMaxTInt ) + { + //unexpected characters or size too big + iError = ( error ) ? error: EHttpInsufficientStorage ; + iContext = EError; + return EFalse; + } + iChunkSize = size; + //skip white spaces + lex.SkipSpace(); + if ( !lex.Eos() ) + { + //unexpected characters + iError = KErrGeneral; + iContext = EError; + return EFalse; + } + if ( lineFeed != KErrNotFound ) + { + //the whole chunk header is parsed + aBuffer.Delete( aPos, lineFeed + UpnpString::KLineFeed().Length() ); + //chunk size == 0 + if ( !iChunkSize ) + { + iContext = ELastChunk; + } + else + { + iContext = EBody; + } + return ( aPos == aBuffer.Length() ); + } + else if ( semiColon != KErrNotFound ) + { + //extension found, + //one character left - possible linefeed + if ( aPos= aBuffer.Length() ); + } + +// ----------------------------------------------------------------------------- +// CUpnpHttpChunkParser::IsFinished +// Checks if decoding ended +// ----------------------------------------------------------------------------- +// +TBool CUpnpHttpChunkParser::IsFinished() + { + return ( iContext==EFinish ); + } + + +// End Of File