diff -r 000000000000 -r 094583676ce7 presadap12/Parser2/SrcXmlParser/CPEngXMLParser.cpp --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/presadap12/Parser2/SrcXmlParser/CPEngXMLParser.cpp Thu Dec 17 08:41:52 2009 +0200 @@ -0,0 +1,1081 @@ +/* +* Copyright (c) 2004 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: XML Parser implementation +* +*/ + +// INCLUDE FILES + +#include +#include +#include +#include + +#include "CPEngXMLParser.h" +#include "MPEngAdvTransactionStatus2.h" +#include "CPEngParserStack.h" + + + + +// =================== MACROS ======================= +#define STORE_AND_RETURN_IF_IN_ERROR( aParser, aErr ) \ + if ( aErr < KErrNone ) \ + { \ + aParser->SetError( aErr ); \ + return NW_STAT_FAILURE; \ + } \ + + + +// ================= LOCAL FUNCTIONS ======================= +/** + * Maps given CSP status code to WV error code range + * defined in PEngWVPresenceErrors.h + * + * @since 3.0 + * @param aCSPStatusCode The CSP status code to map. + * @return WV Error code. + */ +TInt MapWVCspStatusToError( TInt aCSPStatusCode ) + { + //Map the CSP successful (200) ==> KErrNone + if ( aCSPStatusCode == 200 ) + { + return KErrNone; + } + + return KPEngErrorWVServerResponseBase - aCSPStatusCode; + } + + +/** + * Checks is the given CSP status code in the CSP status code range. + * + * @since 3.0 + * @param aCSPStatusCode The CSP status code to check. + * @return ETrue if the given int is inside of the CSP status code range. + * Else EFalse. + */ +TInt IsInCspStatusCodeRange( TInt aCSPStatusCode ) + { + return ( aCSPStatusCode >= KPEngWVStatusCodeBase ) && + ( aCSPStatusCode <= KPEngWVStatusCodeTop ); + } + + +/** + * Decodes given CSP status code descriptor block + * to WV error code. + * + * @since 3.0 + * @param aCSPStatusCode The CSP status code to map. + * @param aWVErrorCode The mapped error code + * @return ETrue if the decode was successful. + * Else EFalse. + */ +TBool DecodeWVCspStatusCodeToError( const TDesC8& aCSPStatusCode, + TInt& aWVErrorCode ) + { + //Try decode the CSP status code to integer & map it to WV Error Code + TInt cspStatusInt; + TLex8 lexer( aCSPStatusCode ); + lexer.SkipSpace(); + TInt lexErr = lexer.Val( cspStatusInt ); + if ( lexErr == KErrNone ) + { + if ( IsInCspStatusCodeRange( cspStatusInt ) ) + { + aWVErrorCode = MapWVCspStatusToError( cspStatusInt ); + return ETrue; + } + } + + return EFalse; + } + + + + + + + +// ================= MEMBER FUNCTIONS ======================= + + +// Two-phased constructor. +EXPORT_C CPEngXMLParser* CPEngXMLParser::NewLC() + { + CPEngXMLParser* self = new ( ELeave ) CPEngXMLParser; + + CleanupStack::PushL( self ); + self->ConstructL(); + + return self; + } + +// Destructor +CPEngXMLParser::~CPEngXMLParser() + { + iResults.Close(); + delete iIntervals; + + +#if _BullseyeCoverage + cov_write(); +#endif + } + + + +// C++ default constructor can NOT contain any code, that +// might leave. +// +CPEngXMLParser::CPEngXMLParser() + { + } + +// Symbian OS default constructor can leave. +void CPEngXMLParser::ConstructL() + { + iIntervals = CPEngParserStack::NewL(); + + iCallBacks.StartDocument_CB = StartDocument_CB; //StartDocument_CB; + iCallBacks.EndDocument_CB = EndDocument_CB; //EndDocument_CB; + iCallBacks.Tag_Start_CB = Tag_Start_CB; + iCallBacks.Attr_Start_CB = NULL; //Attr_Start_CB; + iCallBacks.Attr_VarVal_CB = NULL; //Attr_VarVal_CB; + iCallBacks.Attributes_End_CB = NULL; //Attributes_End_CB; + iCallBacks.Tag_End_CB = Tag_End_CB; + iCallBacks.Content_CB = NULL; //Content_CB; + iCallBacks.Cdata_CB = NULL; //Cdata_CB; + iCallBacks.Comment_CB = NULL; //Comment_CB; + iCallBacks.PiForm_CB = NULL; //PiForm_CB; + iCallBacks.Exception_CB = Exception_CB; // Mostly for debugging purposes + iCallBacks.Extension_CB = NULL; //Extension_CB; + iCallBacks.Attr_Entity_VarVal_CB = NULL; //Attr_Entity_VarVal_CB; + + + iCallBacks.pClientPointer = ( void* ) this; + } + + + + +// --------------------------------------------------------- +// CPEngAttributeLibraryModel::DecodeL() +// +// --------------------------------------------------------- +// +TBool CPEngXMLParser::DecodeL( const TDesC8& aBuffer, + const TDesC8& aString, + TBool aTags, + TInt aLevel ) + { + iMaxParseLevel = aLevel; + iData.Set( aBuffer ); + iSearchable.Set( aString ); + iIncludeTags = aTags; + ResetResults(); + + + NW_XML_Reader_InitFromBuffer( &iReader, aBuffer.Size(), const_cast( iData.Ptr() ) ); + NW_XML_Reader_SetEncoding( &iReader, HTTP_iso_8859_1 ); + + + //Parse & Handle Errors + NW_Status_t status = NW_XML_Parse( &iReader, &iCallBacks ); + if ( iError != KErrNone ) + { + User::Leave( iError ); + } + + if ( status == NW_STAT_OUT_OF_MEMORY ) + { + User::Leave( KErrNoMemory ); + } + + if ( status != NW_STAT_SUCCESS ) + { + User::Leave( KPEngNwErrInternalServerOrNetworkError ); + } + + //And return did we find something + if ( iResults.Count() > 0 ) + { + return ETrue; + } + else + { + return EFalse; + } + } + + + +// --------------------------------------------------------- +// CPEngXMLParser::Count() +// Returns the result count +// --------------------------------------------------------- +// +TInt CPEngXMLParser::Count() + { + return iResults.Count(); + } + + + +// --------------------------------------------------------- +// CPEngXMLParser::ResultL() +// --------------------------------------------------------- +// +TPtrC8 CPEngXMLParser::ResultL( TInt aIndex ) + { + //Get plain result + if ( aIndex >= iResults.Count() || aIndex < 0 ) + { + User::Leave( KErrArgument ); + } + + return iResults[aIndex]; + } + + +// --------------------------------------------------------- +// CPEngXMLParser::ResultAsNarrowTextL() +// --------------------------------------------------------- +// +HBufC8* CPEngXMLParser::ResultAsNarrowTextL( TInt aIndex ) + { + //Performed steps: + //1. UnEscapes XML entities. + + return DoXMLUnEscapingL( ResultL( aIndex ) ); + } + + + +// --------------------------------------------------------- +// CPEngXMLParser::ResultAsUnicodeTextL() +// --------------------------------------------------------- +// +HBufC16* CPEngXMLParser::ResultAsUnicodeTextL( TInt aIndex ) + { + // Performed steps: + // 1. UnEscapes XML entities. + // 2. Converts text from Utf8 to Unicode. + + HBufC8* xmlUnEscaped = DoXMLUnEscapingL( ResultL( aIndex ) ); + + CleanupStack::PushL( xmlUnEscaped ); + HBufC16* unicode = CnvUtfConverter::ConvertToUnicodeFromUtf8L( *xmlUnEscaped ); + CleanupStack::PopAndDestroy( xmlUnEscaped ); + + return unicode; + } + + +// --------------------------------------------------------- +// CPEngXMLParser::ResultAsWVAddressL() +// --------------------------------------------------------- +// +HBufC16* CPEngXMLParser::ResultAsWVAddressL( TInt aIndex ) + { + // Performed steps: + // 1. UnEscapes XML entities. + // 2. Converts text from Utf8 to Unicode. + // 3. UnEscapes WV Address characters + + HBufC8* xmlUnEscaped = DoXMLUnEscapingL( ResultL( aIndex ) ); + + CleanupStack::PushL( xmlUnEscaped ); + HBufC16* unicode = CnvUtfConverter::ConvertToUnicodeFromUtf8L( *xmlUnEscaped ); + CleanupStack::PopAndDestroy( xmlUnEscaped ); + + + CleanupStack::PushL( unicode ); + HBufC16* wvAddress = DoWVAddressUnescapeL( *unicode ); + CleanupStack::PopAndDestroy( unicode ); + + + return wvAddress; + } + + + +// --------------------------------------------------------- +// CPEngXMLParser::ResultAsBase64DecodedL() +// --------------------------------------------------------- +// +HBufC8* CPEngXMLParser::ResultAsBase64DecodedL( TInt aIndex ) + { + // Performed steps: + // 1. Coverts data from the BASE64 format + + + HBufC8* decodedBuffer8 = HBufC8::NewLC( ResultL( aIndex ).Length() ); + TPtr8 decodedPtr8( decodedBuffer8->Des() ); + + TImCodecB64 base64Decoder; + base64Decoder.Initialise(); + + // Decode returns ETrue, more data is needed to complete the decoding + // ==> in this case the received buffer is considered as corrupted + TBool moreDataNeeded = base64Decoder.Decode( ResultL( aIndex ), decodedPtr8 ); + if ( moreDataNeeded ) + { + User::Leave( KErrCorrupt ); + } + + decodedBuffer8 = decodedBuffer8->ReAllocL( decodedBuffer8->Length() ); + CleanupStack::Pop(); //decodedBuffer8 + return decodedBuffer8; + } + + +// --------------------------------------------------------- +// CPEngXMLParser::ParseResultL() +// Parses the generic WV result from the XML packet +// --------------------------------------------------------- +// +TInt CPEngXMLParser::ParseResultL( const TDesC8& aBuffer, + TInt aOperationID, + MPEngAdvTransactionStatus2& aStatus, + TBool& aResultRequired ) + { + return DoParseResultL( aBuffer, + aStatus, + aOperationID, + NULL, + NULL, + aResultRequired ); + } + + +// --------------------------------------------------------- +// CPEngXMLParser::ParseResultL() +// Parses the generic WV result from the XML packet +// --------------------------------------------------------- +// +TInt CPEngXMLParser::ParseResultL( const TDesC8& aBuffer, + TInt aOperationID, + MPEngAdvTransactionStatus2& aStatus ) + { + //By default - result is required + TBool resultRequired = ETrue; + return DoParseResultL( aBuffer, + aStatus, + aOperationID, + NULL, + NULL, + resultRequired ); + } + + + +// --------------------------------------------------------- +// CPEngXMLParser::ParseContactListResultL() +// Parses the contact list related WV result from the +// XML packet. +// --------------------------------------------------------- +// +TInt CPEngXMLParser::ParseContactListResultL( const TDesC8& aBuffer, + TInt aOperationID, + const TDesC& aContactList, + MPEngAdvTransactionStatus2& aStatus ) + { + //By default - result is required + TBool resultRequired = ETrue; + return DoParseResultL( aBuffer, + aStatus, + aOperationID, + NULL, + &aContactList, + resultRequired ); + } + + + +// --------------------------------------------------------- +// CPEngXMLParser::Close() +// --------------------------------------------------------- +// +void CPEngXMLParser::Close() + { + delete this; + } + + + +// --------------------------------------------------------- +// CPEngXMLParser::ResetResults() +// --------------------------------------------------------- +// +void CPEngXMLParser::ResetResults() + { + iResults.Reset(); + iIntervals->Reset(); + iParsingLevel = 0; + iError = KErrNone; + } + + + + +// --------------------------------------------------------- +// CPEngXMLParser::DoWVAddressUnescapeL() +// --------------------------------------------------------- +// +HBufC16* CPEngXMLParser::DoWVAddressUnescapeL( const TDesC16& aSrc ) + { + HBufC16* destBuffer = HBufC16::NewLC( aSrc.Length() ); + TPtr16 dest( destBuffer->Des() ); + + + // the length of the escape sequence, without the percent sign + TBuf8<2> value; + + TInt srcLen( aSrc.Length() ); + for ( TInt i( 0 ); i < srcLen; i++ ) + { + if ( aSrc[i] == '%' ) + { + // check if there is enough characters to resolve the next real, + // unescaped character + if ( ( i + 2 ) >= srcLen ) + { + // not enough chars to resolve the last escaped sequence + // bail out + break; + } + // let's take the next two characters, the encoded char is + // of format %20 + value.Zero(); + value.Append( aSrc[++i] ); + value.Append( aSrc[++i] ); + + // find the hexadecimal value from the string + // and convert it to a character + TLex8 lexer( value ); + TUint8 charVal; + TInt retVal( lexer.Val( charVal, EHex ) ); + if ( retVal == KErrGeneral ) + { + // could not convert escape chars to character value + // just append the percent sign and characters + dest.Append( '%' ); + dest.Append( value[0] ); + dest.Append( value[1] ); + } + else if ( retVal != KErrNone ) + { + User::Leave( retVal ); + } + else + { + // append the found character to the destination buffer + TChar escapedChar( charVal ); + dest.Append( escapedChar ); + } + } + else + { + // the character wasn't any escaped sequence starter -> just copy it + dest.Append( aSrc[i] ); + } + } + + + destBuffer = destBuffer->ReAllocL( destBuffer->Length() ); + CleanupStack::Pop(); //old destBuffer + return destBuffer; + } + + + +// --------------------------------------------------------- +// CPEngXMLParser::DoXMLUnEscaping() +// Decodes the XML escaped character sequences +// --------------------------------------------------------- +// +HBufC8* CPEngXMLParser::DoXMLUnEscapingL( const TDesC8& aSrc ) + { + HBufC8* destBuffer = HBufC8::NewLC( aSrc.Length() ); + TPtr8 dest( destBuffer->Des() ); + + TInt srcLen( aSrc.Length() ); + for ( TInt i( 0 ); i < srcLen; i++ ) + { + if ( aSrc[i] == '&' ) + { + // check if there is enough characters to resolve the next real, + // unescaped character + if ( ( i + 2 ) >= srcLen ) + { + // not enough chars to resolve the last escaped sequence + // bail out + break; + } + if ( aSrc[i+1] == 'a' ) + { + // only two possibilities if the escape string starts + // with &a + if ( aSrc[i+2] == 'm' ) + { + dest.Append( '&' ); + i += 4; // jump over rest of the & string + } + else + { + dest.Append( '\'' ); + i += 5; // jump over rest of the ' string + } + } + else if ( aSrc[i+1] == 'g' ) + { + dest.Append( '>' ); + i += 3; // jump over rest of the > string + } + else if ( aSrc[i+1] == 'l' ) + { + dest.Append( '<' ); + i += 3; // jump over rest of the < string + } + else if ( aSrc[i+1] == 'q' ) + { + dest.Append( '\"' ); + i += 5; // jump over rest of the " string + } + else + { + User::Leave( KErrCorrupt ); + } + } + else + { + dest.Append( aSrc[i] ); + } + } + + destBuffer = destBuffer->ReAllocL( destBuffer->Length() ); + CleanupStack::Pop(); //old destBuffer + return destBuffer; + } + + + + +// --------------------------------------------------------- +// CPEngXMLParser::DoParseResultL() +// Parses the WV result from the XML packet. +// --------------------------------------------------------- +// +TInt CPEngXMLParser::DoParseResultL( const TDesC8& aBuffer, + MPEngAdvTransactionStatus2& aStatus, + TInt aOperationID, + const TUint32* aAttributeTypeID, + const TDesC* aContactListID, + TBool& aResultRequired ) + { + //DTD: Result (Code, Description?, DetailedResult*) + + TPtrC8 resultBlock( NULL, 0 ); + TInt wvErrorCode = KErrNone; + TBool errorCodeDecoded = EFalse; + + + //Look for mandatory parts + if ( DecodeL( aBuffer, KResultXMLTag, ETrue ) ) + { + resultBlock.Set( ResultL() ); + if ( DecodeL( resultBlock, KCodeXMLTag, EFalse ) ) + { + TPtrC8 cspStatusCodeBlock( ResultL() ); + errorCodeDecoded = DecodeWVCspStatusCodeToError( cspStatusCodeBlock, + wvErrorCode ); + } + } + + + //And act wether the mandatory part was found or not.. + if ( !errorCodeDecoded ) + { + if ( aResultRequired ) + { + aStatus.SetStatus( KPEngNwErrInternalServerOrNetworkError ); + } + else + { + aStatus.SetStatus( KErrNone ); + } + + //Return to client that mandatory part wasn't found + aResultRequired = EFalse; + } + + + else + { + //Mandatory part fine. Return it also to client. + aStatus.SetStatus( wvErrorCode ); + aResultRequired = ETrue; + + + //Process possible detailed entries + TInt detailEntriesStartCount = aStatus.DetailedResultCount(); + if ( wvErrorCode == KPEngNwErrPartiallySuccessful ) + { + DoParseDetailedResultsL( resultBlock, + aStatus, + aOperationID, + aAttributeTypeID, + aContactListID ); + } + TInt detailEntriesEndCount = aStatus.DetailedResultCount(); + + + + if ( detailEntriesStartCount == detailEntriesEndCount ) + { + //No detail entries added ==> + //Look for description and if having a valid one, + //add it as a detail + + //Parse only 2 tag levels. + //(Check the the result packet DTD.) + if ( DecodeL( resultBlock, KDescriptionXMLTag, EFalse, 2 ) ) + { + HBufC* descriptionBuf = ResultAsUnicodeTextL(); + CleanupStack::PushL( descriptionBuf ); + if ( descriptionBuf->Length() > 0 ) + { + aStatus.AddDetailedResultL( aOperationID, wvErrorCode, + aAttributeTypeID, NULL, + aContactListID, descriptionBuf ); + } + + CleanupStack::PopAndDestroy( descriptionBuf ); + } + } + } + + + return aStatus.Status(); + } + + + +// --------------------------------------------------------- +// CPEngXMLParser::DoParseDetailedResultsL() +// --------------------------------------------------------- +// +void CPEngXMLParser::DoParseDetailedResultsL( const TDesC8& aBuffer, + MPEngAdvTransactionStatus2& aStatus, + TInt aOperationID, + const TUint32* aAttributeTypeID, + const TDesC* aContactListID ) + { + CPtrC8Array* detailedResults = new ( ELeave ) CPtrC8Array( 5 ); + CleanupStack::PushL( detailedResults ); + + if ( DecodeL( aBuffer, KDetailedResultXMLTag, ETrue ) ) + { + //Gather detailed result blocks.. + const TInt detailedResultCount = Count(); + TInt ii; + for ( ii = 0; ii < detailedResultCount; ii++ ) + { + detailedResults->AppendL( ResultL( ii ) ); + } + + + //And handle each detailed result block.. + for ( ii = 0; ii < detailedResultCount; ii++ ) + { + DoParseOneDetailedResultL( ( *detailedResults )[ ii ], + aStatus, + aOperationID, + aAttributeTypeID, + aContactListID ); + } + } + + CleanupStack::PopAndDestroy( detailedResults ); + } + + + +// --------------------------------------------------------- +// CPEngXMLParser::DoParseOneDetailedResultL() +// --------------------------------------------------------- +// +void CPEngXMLParser::DoParseOneDetailedResultL( const TDesC8& aDetailedResult, + MPEngAdvTransactionStatus2& aStatus, + TInt aOperationID, + const TUint32* aAttributeTypeID, + const TDesC* aContactListID ) + { + //DTD: DetailedResult (Code, Description?, UserID*, GroupID*, + // ScreenName*, MessageID*, ContactList*, Domain*) + + TInt wvErrorCode = KErrNone; + TBool errorCodeDecoded = EFalse; + + + //Look for mandatory parts + if ( DecodeL( aDetailedResult, KCodeXMLTag, EFalse ) ) + { + TPtrC8 cspStatusCodeBlock( ResultL() ); + errorCodeDecoded = DecodeWVCspStatusCodeToError( cspStatusCodeBlock, + wvErrorCode ); + } + + + + if ( !errorCodeDecoded ) + { + //Detailed result is somehow malformed... + aStatus.AddDetailedResultL( aOperationID, + KPEngNwErrInternalServerOrNetworkError, + aAttributeTypeID, NULL, + aContactListID, NULL ); + } + + + else + { + //Detailed result mandatory parts ok + //Get the detailed description if any + HBufC* descriptionBuf = NULL; + if ( DecodeL( aDetailedResult, KDescriptionXMLTag, EFalse ) ) + { + descriptionBuf = ResultAsUnicodeTextL(); + if ( descriptionBuf->Length() == 0 ) + { + delete descriptionBuf; + descriptionBuf = NULL; + } + } + if ( descriptionBuf ) + { + CleanupStack::PushL( descriptionBuf ); + } + + + + // And process the detailed "main" entries + TInt detailMainEntriesStartCount = aStatus.DetailedResultCount(); + { + //First user id's + if ( DecodeL( aDetailedResult, KUserIDXMLTag, EFalse ) ) + { + const TInt detailedUserIDsCount = Count(); + + for ( TInt ii( 0 ); ii < detailedUserIDsCount; ii++ ) + { + HBufC* userID = ResultAsWVAddressL( ii ); + CleanupStack::PushL( userID ); + if ( userID->Length() > 0 ) + { + aStatus.AddDetailedResultL( aOperationID, wvErrorCode, + aAttributeTypeID, userID, + aContactListID, descriptionBuf ); + + } + + CleanupStack::PopAndDestroy( userID ); + } + } + + if ( DecodeL( aDetailedResult, KContactList, EFalse ) ) + { + const TInt detailedContactListsCount = Count(); + + for ( TInt ii( 0 ); ii < detailedContactListsCount; ii++ ) + { + HBufC* contactList = ResultAsWVAddressL( ii ); + CleanupStack::PushL( contactList ); + if ( contactList->Length() > 0 ) + { + aStatus.AddDetailedResultL( aOperationID, wvErrorCode, + aAttributeTypeID, NULL, + contactList, descriptionBuf ); + + } + + CleanupStack::PopAndDestroy( contactList ); + } + } + } + + TInt detailMainEntriesEndCount = aStatus.DetailedResultCount(); + + + + + if ( detailMainEntriesStartCount == detailMainEntriesEndCount ) + { + //No main type entries added ==> add code and possible + //description as one + aStatus.AddDetailedResultL( aOperationID, + wvErrorCode, + NULL, + NULL, + NULL, + descriptionBuf ); + } + + + if ( descriptionBuf ) + { + CleanupStack::PopAndDestroy( descriptionBuf ); + } + } + } + + + +// --------------------------------------------------------- +// CPEngXMLParser::SetError() +// --------------------------------------------------------- +// +void CPEngXMLParser::SetError( TInt aError ) + { + iError = aError; + } + + + + +// ==================== cXML CALLBACK FUNCTIONS ==================== +// --------------------------------------------------------- +// CPEngXMLParser::StartDocument_CB() +// --------------------------------------------------------- +// +NW_Status_t CPEngXMLParser::StartDocument_CB( NW_XML_Reader_t*, void* ) + { + //No leaving code allowed + return NW_STAT_SUCCESS; + } + + +// --------------------------------------------------------- +// CPEngXMLParser::EndDocument_CB() +// --------------------------------------------------------- +// +NW_Status_t CPEngXMLParser::EndDocument_CB( NW_XML_Reader_t*, void* ) + { + //No leaving code allowed + return NW_STAT_SUCCESS; + } + + +// --------------------------------------------------------- +// CPEngXMLParser::Tag_Start_CB() +// --------------------------------------------------------- +// +NW_Status_t CPEngXMLParser::Tag_Start_CB( NW_XML_Reader_t* /*aReader*/, + const NW_XML_Reader_Interval_t* aName, + void* aParser ) + { + //No leaving code allowed + + CPEngXMLParser* parser = reinterpret_cast ( aParser ); + + parser->iParsingLevel++; + + TInt len( aName->stop - aName->start ); + TPtrC8 buffer( parser->iData.Mid( aName->start, len ) ); + + // now check if the found tag was the one we were looking for + if ( buffer.Compare( parser->iSearchable ) == 0 ) + { + TUint itemStart; + if ( parser->iIncludeTags ) + { + // the interval includes the tag and the first '<' also + itemStart = aName->start - 1; + } + else + { + //Locate next tag end char + TPtrC8 fullRemainder( parser->iData.Mid( aName->start ) ); + TInt endMarkOffset = fullRemainder.Locate( '>' ); + STORE_AND_RETURN_IF_IN_ERROR( parser, endMarkOffset ); + + // here the interval doesn't include the tag nor the ending '>' + itemStart = aName->start + endMarkOffset + 1; + } + + TInt err = parser->iIntervals->PushStart( itemStart ); + STORE_AND_RETURN_IF_IN_ERROR( parser, err ); + } + + return NW_STAT_SUCCESS; + } + + + + + +// --------------------------------------------------------- +// CPEngXMLParser::Tag_End_CB() +// --------------------------------------------------------- +// +NW_Status_t CPEngXMLParser::Tag_End_CB( NW_XML_Reader_t* /*aReader*/, + const NW_XML_Reader_Interval_t* aName, + NW_Uint32 /*emptyTagFlag*/, + void* aParser ) + { + + //No leaving code allowed + CPEngXMLParser* parser = reinterpret_cast ( aParser ); + + TInt len( aName->stop - aName->start ); + TPtrC8 buffer( parser->iData.Mid( aName->start, len ) ); + + // check the current XML level + // now check if the found tag was the one we were looking for + if ( buffer.Compare( parser->iSearchable ) == 0 ) + { + TUint itemEnd; + if ( parser->iIncludeTags ) + { + // the interval includes the tag and the last '>' also + + //Locate next end char + TPtrC8 fullRemainder( parser->iData.Mid( aName->stop ) ); + TInt endMarkOffset = fullRemainder.Locate( '>' ); + STORE_AND_RETURN_IF_IN_ERROR( parser, endMarkOffset ); + + itemEnd = aName->stop + endMarkOffset + 1; + } + else + { + // here the interval doesn't include the tag nor the starting 'start - 2; + } + + + TInt err = parser->iIntervals->PushEnd( itemEnd ); + STORE_AND_RETURN_IF_IN_ERROR( parser, err ); + + + // next grab the data between the tags from the original XML data, + //if we are at allowed level + if ( ( parser->iMaxParseLevel == 0 ) || + ( parser->iParsingLevel <= parser->iMaxParseLevel ) ) + { + TPoint dataInterval( parser->iIntervals->Pop() ); + TInt intervalLength( dataInterval.iY - dataInterval.iX ); + + + TPtrC8 resultSection( NULL, 0 ); + if ( intervalLength > 0 ) // if the stack was broken, the length will be 0 + { + resultSection.Set( parser->iData.Mid( dataInterval.iX, intervalLength ) ); + } + + + TInt err = parser->iResults.Append( resultSection ); + STORE_AND_RETURN_IF_IN_ERROR( parser, err ); + } + } + + + parser->iParsingLevel--; + return NW_STAT_SUCCESS; + } + + + + + +// --------------------------------------------------------- +// CPEngXMLParser::Attr_Start_CB() +// --------------------------------------------------------- +// +NW_Status_t CPEngXMLParser::Attr_Start_CB( NW_XML_Reader_t*, + const NW_XML_Reader_Interval_t* /*pI_name*/, + void* ) + { + //No leaving code allowed + + return NW_STAT_SUCCESS; + } + + +// --------------------------------------------------------- +// CPEngXMLParser::Attr_VarVal_CB() +// --------------------------------------------------------- +// +NW_Status_t CPEngXMLParser::Attr_VarVal_CB( NW_XML_Reader_t*, + const NW_XML_Reader_Interval_t* /*pI_name*/, + const NW_XML_Reader_Interval_t* /*pI_value*/, + void* ) + + { + //No leaving code allowed + + return NW_STAT_SUCCESS; + } + + + +// --------------------------------------------------------- +// CPEngXMLParser::Attributes_End_CB() +// --------------------------------------------------------- +// +NW_Status_t CPEngXMLParser::Attributes_End_CB( NW_XML_Reader_t*, + NW_Uint32 /*attributeCount*/, + void* ) + { + //No leaving code allowed + + return NW_STAT_SUCCESS; + } + + + +// --------------------------------------------------------- +// CPEngXMLParser::Attr_Entity_VarVal_CB() +// --------------------------------------------------------- +// +NW_Status_t CPEngXMLParser::Attr_Entity_VarVal_CB ( NW_XML_Reader_t* /*pT*/, + const NW_XML_Reader_Interval_t* /*pI_name*/, + NW_Uint8* /*pValue*/, + NW_Uint32 /*valueByteLength*/, + void* /*pV*/ ) + { + //No leaving code allowed + + return NW_STAT_SUCCESS; + } + + +// --------------------------------------------------------- +// CPEngXMLParser::Exception_CB() +// --------------------------------------------------------- +// +NW_Status_t CPEngXMLParser::Exception_CB( NW_XML_Reader_t*, void* ) + { + //No leaving code allowed + + return NW_STAT_FAILURE; + } + + +// End of File + +