diff -r 3785f754ee62 -r 5360b7ddc251 upnpavcontroller/upnpxmlparser/src/upnpxmlparser.cpp --- a/upnpavcontroller/upnpxmlparser/src/upnpxmlparser.cpp Fri Sep 17 08:31:21 2010 +0300 +++ b/upnpavcontroller/upnpxmlparser/src/upnpxmlparser.cpp Mon Nov 01 12:37:49 2010 +0200 @@ -1,697 +1,698 @@ -/* -* Copyright (c) 2008 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 SAX Parser for UPnP. -* -*/ - - - - - - -// INCLUDE FILES -// xml parser api -#include -#include -#include -#include - -// upnp stack api -#include "upnpstring.h" -#include -#include -#include "upnpelement.h" -#include "upnpxmlparser.h" - -// upnpframework / internal api's -#include "upnpcdsreselementutility.h" - -// xmlparser internal -#include "upnpobjectstack.h" -#include "upnpitemtoxml.h" -#include "upnpxmlstringutility.h" -#include "upnpxmlparser.h" - -_LIT( KComponentLogfile, "upnpxmlparser.txt"); -#include "upnplog.h" - - -_LIT8( KXmlMimeType, "text/xml" ); -_LIT8( KLIB2XML, "libxml2" ); - -_LIT8( KContainer, "container" ); -_LIT8( KItem, "item" ); - -_LIT8( KTitle, "title" ); - -_LIT8( KClass, "class" ); -_LIT8( KContentURI, "res" ); -_LIT8( KId, "id" ); -_LIT8( KParentId, "parentId" ); -_LIT8( KRestricted, "restricted" ); -_LIT8( KComma, ":" ); -_LIT8( KTrue, "1" ); -_LIT8( KDIDL, "DIDL-Lite" ); -_LIT8( KDesc, "desc" ); -_LIT8( KDlnaDoc, "X_DLNADOC" ); -_LIT8( KSpace, " " ); -_LIT8( KImportUri, "importUri" ); - -// -------------------------------------------------------------------------- -// CUPnPXMLParser::CUPnPXMLParser() -// See upnpxmlparser.h -// -------------------------------------------------------------------------- -CUPnPXMLParser::CUPnPXMLParser() - { - } - -// -------------------------------------------------------------------------- -// CUPnPXMLParser::ConstructL -// See upnpxmlparser.h -// -------------------------------------------------------------------------- -void CUPnPXMLParser::ConstructL() - { - __LOG( "CUPnPXMLParser::CostructL" ); - iStack = CUPnPObjectStack::NewL(); - } - -// -------------------------------------------------------------------------- -// CUPnPXMLParser::NewL -// See upnpxmlparser.h -// -------------------------------------------------------------------------- -EXPORT_C CUPnPXMLParser* CUPnPXMLParser::NewL() - { - CUPnPXMLParser* self = CUPnPXMLParser::NewLC(); - CleanupStack::Pop( self ); - return self; - } - - -// -------------------------------------------------------------------------- -// CUPnPXMLParser::NewLC -// See upnpxmlparser.h -// -------------------------------------------------------------------------- -EXPORT_C CUPnPXMLParser* CUPnPXMLParser::NewLC() - { - CUPnPXMLParser* self = new( ELeave ) CUPnPXMLParser(); - CleanupStack::PushL( self ); - self->ConstructL(); - return self; - } - -// -------------------------------------------------------------------------- -// CUPnPXMLParser::~CUPnPXMLParser -// See upnpxmlparser.h -// -------------------------------------------------------------------------- -CUPnPXMLParser::~CUPnPXMLParser() - { - __LOG( "CUPnPXMLParser::~CUPnPXMLParser" ); - if ( iStack ) - { - iStack->ResetAndDestroy(); - delete iStack; - } - - delete iElementValue; - delete iNewElement; - - } - -// -------------------------------------------------------------------------- -// CUPnPXMLParser::ResetMember -// See upnpxmlparser.h -// -------------------------------------------------------------------------- -void CUPnPXMLParser::ResetMember() - { - iResultRoot->ResetAndDestroy(); - iResultRoot = NULL; - iStack->ResetAndDestroy(); - delete iStack; - iStack = NULL; - - delete iElementValue; iElementValue = NULL; - delete iNewElement; iNewElement = NULL; - iTitle = 0; - iObjectClass = 0; - } - -// -------------------------------------------------------------------------- -// CUPnPXMLParser::ParseResultDataL -// See upnpxmlparser.h -// -------------------------------------------------------------------------- -EXPORT_C void CUPnPXMLParser::ParseResultDataL( - RPointerArray& aResultArray, - const TDesC8& aData ) - { - __LOG( "CUPnPXMLParser::ParseResultDataL, begin" ); - - if ( !aData.Length() ) - { - User::Leave( KErrArgument ); - } - - iResultRoot = &aResultArray; - - // Create parser - CMatchData* matchData = CMatchData::NewLC(); - matchData->SetMimeTypeL( KXmlMimeType ); - matchData->SetVariantL( KLIB2XML ); - CParser* parser = CParser::NewLC( *matchData, *this ); - parser->EnableFeature( Xml::EReportNamespaceMapping ); - - TRAPD( err, Xml::ParseL( *parser,aData ) ); - // if the xml contained control character - if( EXmlInvalidToken == err ) - { - __LOG1 ( "CUPnPXMLParser::ParseResultDataL Can not Parse \ - error code %d " ,err ); - HBufC8* FiltrateBuffer = - UpnpXmlStringUtility::RemoveXmlControlCharactersL( aData ); - //if remove some control characters. - if( FiltrateBuffer ) - { - CleanupStack::PushL( FiltrateBuffer ); - ResetMember(); - - iStack = CUPnPObjectStack::NewL(); - iResultRoot = &aResultArray; - - Xml::ParseL( *parser, *FiltrateBuffer ); - CleanupStack::PopAndDestroy( FiltrateBuffer ); - } - else - { - User::Leave( err ); - } - } - else if ( KErrNone != err ) - { - User::Leave( err ); - } - CleanupStack::PopAndDestroy( parser ); - CleanupStack::PopAndDestroy( matchData ); - - iResultRoot = NULL; - __LOG( "CUPnPXMLParser::ParseResultDataL, end" ); - } - -// -------------------------------------------------------------------------- -// CUPnPXMLParser::ItemAsXMLLC -// See upnpxmlparser.h -// -------------------------------------------------------------------------- -EXPORT_C HBufC8* CUPnPXMLParser::ItemAsXmlLC( const CUpnpItem& aItem ) - { - CUpnpItemToXML* tmpXmlItem = CUpnpItemToXML::NewLC( aItem ); - HBufC8* raw = tmpXmlItem->AsXmlL(); - CleanupStack::PushL( raw ); - - HBufC8* encoded = UpnpString::EncodeXmlStringL( raw ); - CleanupStack::PopAndDestroy( raw ); - CleanupStack::PushL( encoded ); - - HBufC8* tagged = tmpXmlItem->CreateUnDecodedXmlL( *encoded ); - CleanupStack::PopAndDestroy( encoded ); - CleanupStack::PopAndDestroy( tmpXmlItem ); - CleanupStack::PushL( tagged ); - - return tagged; - } - -// -------------------------------------------------------------------------- -// CUPnPXMLParser::XmlForCreateObjectLC -// See upnpxmlparser.h -// -------------------------------------------------------------------------- -EXPORT_C HBufC8* CUPnPXMLParser::XmlForCreateObjectLC( - const CUpnpItem& aItem ) - { - CUpnpItemToXML* tmpXmlItem = CUpnpItemToXML::NewLC( aItem ); - HBufC8* tempXmlDataBlock = tmpXmlItem->AsResultArgumentL(); - CleanupStack::PopAndDestroy( tmpXmlItem ); - CleanupStack::PushL( tempXmlDataBlock ); - - return tempXmlDataBlock; - } - -// -------------------------------------------------------------------------- -// CUPnPXMLParser::ContainerToXmlLC -// See upnpxmlparser.h -// -------------------------------------------------------------------------- -EXPORT_C HBufC8* CUPnPXMLParser::ContainerToXmlLC( - const CUpnpContainer& /*aContainer*/ ) - { - // Not implemented - User::Leave( KErrNotSupported ); - - return NULL; - } - -// -------------------------------------------------------------------------- -// CUPnPXMLParser::OnStartDocumentL -// See upnpxmlparser.h -// -------------------------------------------------------------------------- -void CUPnPXMLParser::OnStartDocumentL( - const RDocumentParameters& /*aDocParam*/, - TInt /*aErrorCode*/ ) - { - // No implementation needed - } - -// -------------------------------------------------------------------------- -// CUPnPXMLParser::OnEndDocumentL -// See upnpxmlparser.h -// -------------------------------------------------------------------------- -void CUPnPXMLParser::OnEndDocumentL( TInt /*aErrorCode*/ ) - { - // No implementation needed - } - -// -------------------------------------------------------------------------- -// CUPnPXMLParser::OnStartElementL -// See upnpxmlparser.h -// -------------------------------------------------------------------------- -void CUPnPXMLParser::OnStartElementL( const RTagInfo& aElement, - const RAttributeArray& aAttributes, - TInt aErrorCode ) - { - __LOG1( "CUPnPXMLParser::OnStartElementL, error code: %d", aErrorCode ); - if ( aErrorCode != KErrNone ) - { - return; - } - const TDesC8& desName = aElement.LocalName().DesC(); - const TDesC8& prefix = aElement.Prefix().DesC(); - - // Delete content, since there may be some stuff between the elements - // (comments, whitespace etc.) - delete iElementValue; iElementValue = NULL; - - if ( !desName.CompareF( KContainer ) ) // Container element - { - CUpnpContainer* tmpContainer = CUpnpContainer::NewL(); - CleanupStack::PushL( tmpContainer ); - - SetAttributesL( *tmpContainer, aAttributes ); - //push into the stack, ownership is transferred - iStack->PushL( tmpContainer ); - - CleanupStack::Pop( tmpContainer ); - } - else if ( !desName.CompareF( KItem ) ) // Item element - { - CUpnpItem* tmpItem = CUpnpItem::NewL(); - CleanupStack::PushL( tmpItem ); - - SetAttributesL( *tmpItem, aAttributes ); - //push into the stack, ownership is transferred - iStack->PushL( tmpItem ); - - CleanupStack::Pop( tmpItem ); - } - else if( !desName.CompareF( KTitle ) ) // Title element - { - // check that we have item or container. cause leave if not - if ( iStack->Count() == 0) - { - User::Leave( KErrArgument ); - } - // We should have an item or a container already! - //__ASSERTD( iStack->Top(), __FILE__, __LINE__ ); - iTitle = ETrue; - } - else if( !desName.CompareF( KClass ) ) // Object class element - { - // check that we have item or container. cause leave if not - if ( iStack->Count() == 0) - { - User::Leave( KErrArgument ); - } - // We should have an item or a container already! - // __ASSERTD( iStack->Top(), __FILE__, __LINE__ ); - iObjectClass = ETrue; - } - // Ignore DIDL-Lite, desc and X_DLNADOC -elements (DLNA req) - else if( desName.Compare( KDIDL ) == KErrNone || - desName.Compare( KDesc ) == KErrNone || - desName.Compare( KDlnaDoc ) == KErrNone - ) - { - // Ignore - } - else - { - // check that we have item or container. cause leave if not - if ( iStack->Count() == 0) - { - User::Leave( KErrArgument ); - } - - // We should have an item or a container already! - //__ASSERTD( iStack->Top(), __FILE__, __LINE__ ); - - if( prefix.Length() > 0 ) // If there is a namespace (upnp: etc) - { - HBufC8* name = HBufC8::NewLC( prefix.Length() + - KComma().Length() + desName.Length() ) ; - name->Des().Copy( prefix ); - name->Des().Append( KComma ); - name->Des().Append( desName ); - - // Create a new element - __ASSERTD( !iNewElement, __FILE__, __LINE__ ); - iNewElement = CUpnpElement::NewL( *name ); - - CleanupStack::PopAndDestroy( name ); - } - else - { - // Create a new element - __ASSERTD( !iNewElement, __FILE__, __LINE__ ); - iNewElement = CUpnpElement::NewL( desName ); - } - - // Set attributes for element - SetAttributesL( aAttributes ); - } - __LOG( "CUPnPXMLParser::OnEndElementL, end" ); - } - -// -------------------------------------------------------------------------- -// CUPnPXMLParser::OnEndElementL -// See upnpxmlparser.h -// -------------------------------------------------------------------------- -void CUPnPXMLParser::OnEndElementL( const RTagInfo& aElement, - TInt aErrorCode ) - { - __LOG( "CUPnPXMLSAXParser::OnEndElementL(), begin" ); - if ( aErrorCode != KErrNone ) - { - return; - } - - const TDesC8& desName = aElement.LocalName().DesC(); - if ( !desName.CompareF( KContainer ) || !desName.CompareF( KItem ) ) - { - iResultRoot->AppendL( iStack->Top() ); - iStack->Pop(); // Remove object from stack. - } - else if( KErrNone != desName.CompareF( KDIDL )) - { - CUpnpObject* obj = (CUpnpObject*)iStack->Top(); - __ASSERTD( obj, __FILE__, __LINE__ ); - - if ( iElementValue ) - { - SetValueToElementL( *obj, *iElementValue ); - } - else - { - SetValueToElementL( *obj, KNullDesC8 ); - } - - delete iElementValue; iElementValue = NULL; - } - __LOG( "CUPnPXMLSAXParser::OnEndElementL(), end" ); - } - -// -------------------------------------------------------------------------- -// CUPnPXMLParser::OnContentL -// See upnpxmlparser.h -// -------------------------------------------------------------------------- -void CUPnPXMLParser::OnContentL( const TDesC8& aBytes, TInt aErrorCode ) - { - __LOG( "CUPnPXMLSAXParser::OnContentL(), begin" ); - if ( !iStack->Count() || aErrorCode != KErrNone ) - { - return; - } - - if( !iElementValue ) //if 1st time - { - iElementValue = HBufC8::NewL(aBytes.Length()); - iElementValue->Des().Copy(aBytes); - } - else - { - HBufC8* previousValue = iElementValue; - iElementValue = HBufC8::NewL( previousValue->Des().Length() + - aBytes.Length() ); - iElementValue->Des().Append( *previousValue ); - iElementValue->Des().Append( aBytes ); - delete previousValue; - } - __LOG( "CUPnPXMLSAXParser::OnContentL(), end" ); - } - -// -------------------------------------------------------------------------- -// CUPnPXMLParser::OnStartPrefixMappingL -// See upnpxmlparser.h -// -------------------------------------------------------------------------- -void CUPnPXMLParser::OnStartPrefixMappingL( const RString& /*aPrefix*/, - const RString& /*aUri*/, - TInt /*aErrorCode*/ ) - { - // No implementation needed - } - -// -------------------------------------------------------------------------- -// CUPnPXMLParser::OnEndPrefixMappingL -// See upnpxmlparser.h -// -------------------------------------------------------------------------- -void CUPnPXMLParser::OnEndPrefixMappingL( const RString& /*aPrefix*/, - TInt /*aErrorCode*/ ) - { - // No implementation needed - } - -// -------------------------------------------------------------------------- -// CUPnPXMLParser::OnIgnorableWhiteSpaceL -// See upnpxmlparser.h -// -------------------------------------------------------------------------- -void CUPnPXMLParser::OnIgnorableWhiteSpaceL( const TDesC8& /*aBytes*/, - TInt /*aErrorCode*/ ) - { - // No implementation needed - } - -// -------------------------------------------------------------------------- -// CUPnPXMLParser::OnSkippedEntityL -// See upnpxmlparser.h -// -------------------------------------------------------------------------- -void CUPnPXMLParser::OnSkippedEntityL( const RString& /*aName*/, - TInt /*aErrorCode*/ ) - { - // No implementation needed - } - -// -------------------------------------------------------------------------- -// CUPnPXMLParser::OnProcessingInstructionL -// See upnpxmlparser.h -// -------------------------------------------------------------------------- -void CUPnPXMLParser::OnProcessingInstructionL( const TDesC8& /*aTarget*/, - const TDesC8& /*aData*/, - TInt /*aErrorCode*/ ) - { - // No implementation needed - } - -// -------------------------------------------------------------------------- -// CUPnPXMLParser::OnError -// See upnpxmlparser.h -// -------------------------------------------------------------------------- -void CUPnPXMLParser::OnError( TInt /*aErrorCode*/ ) - { - // No implementation needed - } - -// -------------------------------------------------------------------------- -// CUPnPXMLParser::GetExtendedInterface -// See upnpxmlparser.h -// -------------------------------------------------------------------------- -TAny* CUPnPXMLParser::GetExtendedInterface( const TInt32 /*aUid*/ ) - { - // No implementation needed - return NULL; - } - -// -------------------------------------------------------------------------- -// CUPnPXMLParser::SetAttributesL -// See upnpxmlparser.h -// -------------------------------------------------------------------------- -void CUPnPXMLParser::SetAttributesL( CUpnpObject& aObject, - const RAttributeArray& aAttributes ) - { - __LOG( "CUPnPXMLParser::SetAttributesL" ); - - if ( iStack->Count() ) - { - // Object has a parent. - // Should not really happen, but implemented anyways - __LOG( "Object has a parent!" ); - - if ( iStack->Top()->ObjectType() != EUPnPContainer ) - { - User::Leave( KErrArgument ); - } - CUpnpContainer* container = (CUpnpContainer*)iStack->Top(); - container->AppendObjectL( aObject ); - } - - RAttribute attribute; - TInt count = aAttributes.Count(); - for ( TInt i = 0 ; i < count; i++ ) // Read attributes. - { - attribute = aAttributes[ i ]; - const TDesC8& name = attribute.Attribute().LocalName().DesC(); - - if( !name.CompareF( KId ) ) - { - aObject.SetIdL( attribute.Value().DesC() ); - } - if( !name.CompareF( KParentId ) ) - { - aObject.SetParentIdL( attribute.Value().DesC() ); - } - if( !name.CompareF( KRestricted ) ) - { - if ( !attribute.Value().DesC().CompareF( KTrue ) ) // restricted - { - aObject.SetRestricted( ETrue ); - } - else // no restriction - { - aObject.SetRestricted( EFalse ); - } - } - } - __LOG( "CUPnPXMLParser::SetAttributesL - End" ); - } - -// -------------------------------------------------------------------------- -// CUPnPXMLParser::SetValueToElementL -// See upnpxmlparser.h -// -------------------------------------------------------------------------- -void CUPnPXMLParser::SetValueToElementL( CUpnpObject& aItem, - const TDesC8& aValue ) - { - __LOG( "CUPnPXMLParser::SetValueToElementL()" ); - - if( iTitle ) - { - __LOG( "SetValueToElementL() - title element" ); - aItem.SetTitleL( aValue ); - iTitle = EFalse; - } - else if( iObjectClass ) - { - __LOG( "SetValueToElementL() - objectclass element" ); - aItem.SetObjectClassL( aValue ); - iObjectClass = EFalse; - } - // See if it's the res-element - else if( iNewElement && // NULL Check - iNewElement->Name().Compare( KContentURI ) == KErrNone ) - { - __LOG( "SetValueToElementL() - res element" ); - - // Check that uri is absolute - if( UpnpCdsResElementUtility::IsUriAbsolute( aValue ) ) - { - __LOG( "valid res-element" ); - iNewElement->SetValueL( aValue ); - aItem.AddElementL( iNewElement ); // Ownership is transferred - iNewElement = NULL; - } - else - { - // if CreateObjectResponse, there is importuri - // no need to check res-element - TInt found = EFalse; - RUPnPAttributesArray elArray = iNewElement->GetAttributes(); - TInt count = elArray.Count(); - for( TInt i = 0; i < count; i++ ) - { - if( elArray[ i ]->Name() == KImportUri ) - { - i = count; - found = ETrue; - __LOG( "SetValueToElementL() - ImportUri found" ); - } - } - - if( found ) - { - __LOG( "no res-element but import uri found" ); - iNewElement->SetValueL( KNullDesC8 ); - aItem.AddElementL( iNewElement ); // Ownership is transferred - iNewElement = NULL; - } - else - { - __LOG( "invalid res-element" ); - delete iNewElement; - iNewElement = NULL; - } - } - - } - else - { - __LOG( "SetValueToElementL() - unknown element" ); - if( iNewElement ) - { - // Check for empty values - if( aValue == KNullDesC8 || aValue == KSpace ) - { - // Do not add empty values - delete iNewElement; iNewElement = NULL; - } - else - { - iNewElement->SetValueL( aValue ); - aItem.AddElementL( iNewElement ); // Ownership is transferred - iNewElement = NULL; - } - } - } - - __LOG( "CUPnPXMLParser::SetValueToElementL() End" ); - } - - -// -------------------------------------------------------------------------- -// CUPnPXMLParser::SetAttributesL -// See upnpxmlparser.h -// -------------------------------------------------------------------------- -void CUPnPXMLParser::SetAttributesL( const RAttributeArray& aAttributes ) - { - __LOG( "CUPnPXMLParser::SetAttributesL" ); - - RAttribute attribute; - TInt count = aAttributes.Count(); - for ( TInt i = 0; i < count ; i++ ) - { - attribute = aAttributes[i]; - const TDesC8& name = attribute.Attribute().LocalName().DesC(); - CUpnpAttribute* att = CUpnpAttribute::NewLC(); - att->SetNameL( name ); - att->SetValueL( attribute.Value().DesC() ); - __ASSERTD( iNewElement, __FILE__, __LINE__ ); - iNewElement->AddAttributeL( att ); - CleanupStack::Pop( att ); - } - __LOG( "CUPnPXMLParser::SetAttributesL End" ); - } - -// end of file - +/* +* Copyright (c) 2008 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 SAX Parser for UPnP. +* +*/ + + + + + + +// INCLUDE FILES +// system / xml parser api +#include +#include +#include +#include + +// upnp stack api +#include + +// dlnasrv / mediaserver api +#include +#include +#include + +// dlnasrv / internal api's +#include "upnpcdsreselementutility.h" + +// dlnasrv / xmlparser internal +#include "upnpobjectstack.h" +#include "upnpitemtoxml.h" +#include "upnpxmlstringutility.h" +#include "upnpxmlparser.h" + +_LIT( KComponentLogfile, "upnpxmlparser.txt"); +#include "upnplog.h" + + +_LIT8( KXmlMimeType, "text/xml" ); +_LIT8( KLIB2XML, "libxml2" ); + +_LIT8( KContainer, "container" ); +_LIT8( KItem, "item" ); + +_LIT8( KTitle, "title" ); + +_LIT8( KClass, "class" ); +_LIT8( KContentURI, "res" ); +_LIT8( KId, "id" ); +_LIT8( KParentId, "parentId" ); +_LIT8( KRestricted, "restricted" ); +_LIT8( KComma, ":" ); +_LIT8( KTrue, "1" ); +_LIT8( KDIDL, "DIDL-Lite" ); +_LIT8( KDesc, "desc" ); +_LIT8( KDlnaDoc, "X_DLNADOC" ); +_LIT8( KSpace, " " ); +_LIT8( KImportUri, "importUri" ); + +// -------------------------------------------------------------------------- +// CUPnPXMLParser::CUPnPXMLParser() +// See upnpxmlparser.h +// -------------------------------------------------------------------------- +CUPnPXMLParser::CUPnPXMLParser() + { + } + +// -------------------------------------------------------------------------- +// CUPnPXMLParser::ConstructL +// See upnpxmlparser.h +// -------------------------------------------------------------------------- +void CUPnPXMLParser::ConstructL() + { + __LOG( "CUPnPXMLParser::CostructL" ); + iStack = CUPnPObjectStack::NewL(); + } + +// -------------------------------------------------------------------------- +// CUPnPXMLParser::NewL +// See upnpxmlparser.h +// -------------------------------------------------------------------------- +EXPORT_C CUPnPXMLParser* CUPnPXMLParser::NewL() + { + CUPnPXMLParser* self = CUPnPXMLParser::NewLC(); + CleanupStack::Pop( self ); + return self; + } + + +// -------------------------------------------------------------------------- +// CUPnPXMLParser::NewLC +// See upnpxmlparser.h +// -------------------------------------------------------------------------- +EXPORT_C CUPnPXMLParser* CUPnPXMLParser::NewLC() + { + CUPnPXMLParser* self = new( ELeave ) CUPnPXMLParser(); + CleanupStack::PushL( self ); + self->ConstructL(); + return self; + } + +// -------------------------------------------------------------------------- +// CUPnPXMLParser::~CUPnPXMLParser +// See upnpxmlparser.h +// -------------------------------------------------------------------------- +CUPnPXMLParser::~CUPnPXMLParser() + { + __LOG( "CUPnPXMLParser::~CUPnPXMLParser" ); + if ( iStack ) + { + iStack->ResetAndDestroy(); + delete iStack; + } + + delete iElementValue; + delete iNewElement; + + } + +// -------------------------------------------------------------------------- +// CUPnPXMLParser::ResetMember +// See upnpxmlparser.h +// -------------------------------------------------------------------------- +void CUPnPXMLParser::ResetMember() + { + iResultRoot->ResetAndDestroy(); + iResultRoot = NULL; + iStack->ResetAndDestroy(); + delete iStack; + iStack = NULL; + + delete iElementValue; iElementValue = NULL; + delete iNewElement; iNewElement = NULL; + iTitle = 0; + iObjectClass = 0; + } + +// -------------------------------------------------------------------------- +// CUPnPXMLParser::ParseResultDataL +// See upnpxmlparser.h +// -------------------------------------------------------------------------- +EXPORT_C void CUPnPXMLParser::ParseResultDataL( + RPointerArray& aResultArray, + const TDesC8& aData ) + { + __LOG( "CUPnPXMLParser::ParseResultDataL, begin" ); + + if ( !aData.Length() ) + { + User::Leave( KErrArgument ); + } + + iResultRoot = &aResultArray; + + // Create parser + CMatchData* matchData = CMatchData::NewLC(); + matchData->SetMimeTypeL( KXmlMimeType ); + matchData->SetVariantL( KLIB2XML ); + CParser* parser = CParser::NewLC( *matchData, *this ); + parser->EnableFeature( Xml::EReportNamespaceMapping ); + + TRAPD( err, Xml::ParseL( *parser,aData ) ); + // if the xml contained control character + if( EXmlInvalidToken == err ) + { + __LOG1 ( "CUPnPXMLParser::ParseResultDataL Can not Parse \ + error code %d " ,err ); + HBufC8* FiltrateBuffer = + UpnpXmlStringUtility::RemoveXmlControlCharactersL( aData ); + //if remove some control characters. + if( FiltrateBuffer ) + { + CleanupStack::PushL( FiltrateBuffer ); + ResetMember(); + + iStack = CUPnPObjectStack::NewL(); + iResultRoot = &aResultArray; + + Xml::ParseL( *parser, *FiltrateBuffer ); + CleanupStack::PopAndDestroy( FiltrateBuffer ); + } + else + { + User::Leave( err ); + } + } + else if ( KErrNone != err ) + { + User::Leave( err ); + } + CleanupStack::PopAndDestroy( parser ); + CleanupStack::PopAndDestroy( matchData ); + + iResultRoot = NULL; + __LOG( "CUPnPXMLParser::ParseResultDataL, end" ); + } + +// -------------------------------------------------------------------------- +// CUPnPXMLParser::ItemAsXMLLC +// See upnpxmlparser.h +// -------------------------------------------------------------------------- +EXPORT_C HBufC8* CUPnPXMLParser::ItemAsXmlLC( const CUpnpItem& aItem ) + { + CUpnpItemToXML* tmpXmlItem = CUpnpItemToXML::NewLC( aItem ); + HBufC8* raw = tmpXmlItem->AsXmlL(); + CleanupStack::PushL( raw ); + + HBufC8* encoded = UpnpString::EncodeXmlStringL( raw ); + CleanupStack::PopAndDestroy( raw ); + CleanupStack::PushL( encoded ); + + HBufC8* tagged = tmpXmlItem->CreateUnDecodedXmlL( *encoded ); + CleanupStack::PopAndDestroy( encoded ); + CleanupStack::PopAndDestroy( tmpXmlItem ); + CleanupStack::PushL( tagged ); + + return tagged; + } + +// -------------------------------------------------------------------------- +// CUPnPXMLParser::XmlForCreateObjectLC +// See upnpxmlparser.h +// -------------------------------------------------------------------------- +EXPORT_C HBufC8* CUPnPXMLParser::XmlForCreateObjectLC( + const CUpnpItem& aItem ) + { + CUpnpItemToXML* tmpXmlItem = CUpnpItemToXML::NewLC( aItem ); + HBufC8* tempXmlDataBlock = tmpXmlItem->AsResultArgumentL(); + CleanupStack::PopAndDestroy( tmpXmlItem ); + CleanupStack::PushL( tempXmlDataBlock ); + + return tempXmlDataBlock; + } + +// -------------------------------------------------------------------------- +// CUPnPXMLParser::ContainerToXmlLC +// See upnpxmlparser.h +// -------------------------------------------------------------------------- +EXPORT_C HBufC8* CUPnPXMLParser::ContainerToXmlLC( + const CUpnpContainer& /*aContainer*/ ) + { + // Not implemented + User::Leave( KErrNotSupported ); + + return NULL; + } + +// -------------------------------------------------------------------------- +// CUPnPXMLParser::OnStartDocumentL +// See upnpxmlparser.h +// -------------------------------------------------------------------------- +void CUPnPXMLParser::OnStartDocumentL( + const RDocumentParameters& /*aDocParam*/, + TInt /*aErrorCode*/ ) + { + // No implementation needed + } + +// -------------------------------------------------------------------------- +// CUPnPXMLParser::OnEndDocumentL +// See upnpxmlparser.h +// -------------------------------------------------------------------------- +void CUPnPXMLParser::OnEndDocumentL( TInt /*aErrorCode*/ ) + { + // No implementation needed + } + +// -------------------------------------------------------------------------- +// CUPnPXMLParser::OnStartElementL +// See upnpxmlparser.h +// -------------------------------------------------------------------------- +void CUPnPXMLParser::OnStartElementL( const RTagInfo& aElement, + const RAttributeArray& aAttributes, + TInt aErrorCode ) + { + __LOG1( "CUPnPXMLParser::OnStartElementL, error code: %d", aErrorCode ); + if ( aErrorCode != KErrNone ) + { + return; + } + const TDesC8& desName = aElement.LocalName().DesC(); + const TDesC8& prefix = aElement.Prefix().DesC(); + + // Delete content, since there may be some stuff between the elements + // (comments, whitespace etc.) + delete iElementValue; iElementValue = NULL; + + if ( !desName.CompareF( KContainer ) ) // Container element + { + CUpnpContainer* tmpContainer = CUpnpContainer::NewL(); + CleanupStack::PushL( tmpContainer ); + + SetAttributesL( *tmpContainer, aAttributes ); + //push into the stack, ownership is transferred + iStack->PushL( tmpContainer ); + + CleanupStack::Pop( tmpContainer ); + } + else if ( !desName.CompareF( KItem ) ) // Item element + { + CUpnpItem* tmpItem = CUpnpItem::NewL(); + CleanupStack::PushL( tmpItem ); + + SetAttributesL( *tmpItem, aAttributes ); + //push into the stack, ownership is transferred + iStack->PushL( tmpItem ); + + CleanupStack::Pop( tmpItem ); + } + else if( !desName.CompareF( KTitle ) ) // Title element + { + // check that we have item or container. cause leave if not + if ( iStack->Count() == 0) + { + User::Leave( KErrArgument ); + } + // We should have an item or a container already! + //__ASSERTD( iStack->Top(), __FILE__, __LINE__ ); + iTitle = ETrue; + } + else if( !desName.CompareF( KClass ) ) // Object class element + { + // check that we have item or container. cause leave if not + if ( iStack->Count() == 0) + { + User::Leave( KErrArgument ); + } + // We should have an item or a container already! + // __ASSERTD( iStack->Top(), __FILE__, __LINE__ ); + iObjectClass = ETrue; + } + // Ignore DIDL-Lite, desc and X_DLNADOC -elements (DLNA req) + else if( desName.Compare( KDIDL ) == KErrNone || + desName.Compare( KDesc ) == KErrNone || + desName.Compare( KDlnaDoc ) == KErrNone + ) + { + // Ignore + } + else + { + // check that we have item or container. cause leave if not + if ( iStack->Count() == 0) + { + User::Leave( KErrArgument ); + } + + // We should have an item or a container already! + //__ASSERTD( iStack->Top(), __FILE__, __LINE__ ); + + if( prefix.Length() > 0 ) // If there is a namespace (upnp: etc) + { + HBufC8* name = HBufC8::NewLC( prefix.Length() + + KComma().Length() + desName.Length() ) ; + name->Des().Copy( prefix ); + name->Des().Append( KComma ); + name->Des().Append( desName ); + + // Create a new element + __ASSERTD( !iNewElement, __FILE__, __LINE__ ); + iNewElement = CUpnpElement::NewL( *name ); + + CleanupStack::PopAndDestroy( name ); + } + else + { + // Create a new element + __ASSERTD( !iNewElement, __FILE__, __LINE__ ); + iNewElement = CUpnpElement::NewL( desName ); + } + + // Set attributes for element + SetAttributesL( aAttributes ); + } + __LOG( "CUPnPXMLParser::OnEndElementL, end" ); + } + +// -------------------------------------------------------------------------- +// CUPnPXMLParser::OnEndElementL +// See upnpxmlparser.h +// -------------------------------------------------------------------------- +void CUPnPXMLParser::OnEndElementL( const RTagInfo& aElement, + TInt aErrorCode ) + { + __LOG( "CUPnPXMLSAXParser::OnEndElementL(), begin" ); + if ( aErrorCode != KErrNone ) + { + return; + } + + const TDesC8& desName = aElement.LocalName().DesC(); + if ( !desName.CompareF( KContainer ) || !desName.CompareF( KItem ) ) + { + iResultRoot->AppendL( iStack->Top() ); + iStack->Pop(); // Remove object from stack. + } + else if( KErrNone != desName.CompareF( KDIDL )) + { + CUpnpObject* obj = (CUpnpObject*)iStack->Top(); + __ASSERTD( obj, __FILE__, __LINE__ ); + + if ( iElementValue ) + { + SetValueToElementL( *obj, *iElementValue ); + } + else + { + SetValueToElementL( *obj, KNullDesC8 ); + } + + delete iElementValue; iElementValue = NULL; + } + __LOG( "CUPnPXMLSAXParser::OnEndElementL(), end" ); + } + +// -------------------------------------------------------------------------- +// CUPnPXMLParser::OnContentL +// See upnpxmlparser.h +// -------------------------------------------------------------------------- +void CUPnPXMLParser::OnContentL( const TDesC8& aBytes, TInt aErrorCode ) + { + __LOG( "CUPnPXMLSAXParser::OnContentL(), begin" ); + if ( !iStack->Count() || aErrorCode != KErrNone ) + { + return; + } + + if( !iElementValue ) //if 1st time + { + iElementValue = HBufC8::NewL(aBytes.Length()); + iElementValue->Des().Copy(aBytes); + } + else + { + HBufC8* previousValue = iElementValue; + iElementValue = HBufC8::NewL( previousValue->Des().Length() + + aBytes.Length() ); + iElementValue->Des().Append( *previousValue ); + iElementValue->Des().Append( aBytes ); + delete previousValue; + } + __LOG( "CUPnPXMLSAXParser::OnContentL(), end" ); + } + +// -------------------------------------------------------------------------- +// CUPnPXMLParser::OnStartPrefixMappingL +// See upnpxmlparser.h +// -------------------------------------------------------------------------- +void CUPnPXMLParser::OnStartPrefixMappingL( const RString& /*aPrefix*/, + const RString& /*aUri*/, + TInt /*aErrorCode*/ ) + { + // No implementation needed + } + +// -------------------------------------------------------------------------- +// CUPnPXMLParser::OnEndPrefixMappingL +// See upnpxmlparser.h +// -------------------------------------------------------------------------- +void CUPnPXMLParser::OnEndPrefixMappingL( const RString& /*aPrefix*/, + TInt /*aErrorCode*/ ) + { + // No implementation needed + } + +// -------------------------------------------------------------------------- +// CUPnPXMLParser::OnIgnorableWhiteSpaceL +// See upnpxmlparser.h +// -------------------------------------------------------------------------- +void CUPnPXMLParser::OnIgnorableWhiteSpaceL( const TDesC8& /*aBytes*/, + TInt /*aErrorCode*/ ) + { + // No implementation needed + } + +// -------------------------------------------------------------------------- +// CUPnPXMLParser::OnSkippedEntityL +// See upnpxmlparser.h +// -------------------------------------------------------------------------- +void CUPnPXMLParser::OnSkippedEntityL( const RString& /*aName*/, + TInt /*aErrorCode*/ ) + { + // No implementation needed + } + +// -------------------------------------------------------------------------- +// CUPnPXMLParser::OnProcessingInstructionL +// See upnpxmlparser.h +// -------------------------------------------------------------------------- +void CUPnPXMLParser::OnProcessingInstructionL( const TDesC8& /*aTarget*/, + const TDesC8& /*aData*/, + TInt /*aErrorCode*/ ) + { + // No implementation needed + } + +// -------------------------------------------------------------------------- +// CUPnPXMLParser::OnError +// See upnpxmlparser.h +// -------------------------------------------------------------------------- +void CUPnPXMLParser::OnError( TInt /*aErrorCode*/ ) + { + // No implementation needed + } + +// -------------------------------------------------------------------------- +// CUPnPXMLParser::GetExtendedInterface +// See upnpxmlparser.h +// -------------------------------------------------------------------------- +TAny* CUPnPXMLParser::GetExtendedInterface( const TInt32 /*aUid*/ ) + { + // No implementation needed + return NULL; + } + +// -------------------------------------------------------------------------- +// CUPnPXMLParser::SetAttributesL +// See upnpxmlparser.h +// -------------------------------------------------------------------------- +void CUPnPXMLParser::SetAttributesL( CUpnpObject& aObject, + const RAttributeArray& aAttributes ) + { + __LOG( "CUPnPXMLParser::SetAttributesL" ); + + if ( iStack->Count() ) + { + // Object has a parent. + // Should not really happen, but implemented anyways + __LOG( "Object has a parent!" ); + + if ( iStack->Top()->ObjectType() != EUPnPContainer ) + { + User::Leave( KErrArgument ); + } + CUpnpContainer* container = (CUpnpContainer*)iStack->Top(); + container->AppendObjectL( aObject ); + } + + RAttribute attribute; + TInt count = aAttributes.Count(); + for ( TInt i = 0 ; i < count; i++ ) // Read attributes. + { + attribute = aAttributes[ i ]; + const TDesC8& name = attribute.Attribute().LocalName().DesC(); + + if( !name.CompareF( KId ) ) + { + aObject.SetIdL( attribute.Value().DesC() ); + } + if( !name.CompareF( KParentId ) ) + { + aObject.SetParentIdL( attribute.Value().DesC() ); + } + if( !name.CompareF( KRestricted ) ) + { + if ( !attribute.Value().DesC().CompareF( KTrue ) ) // restricted + { + aObject.SetRestricted( ETrue ); + } + else // no restriction + { + aObject.SetRestricted( EFalse ); + } + } + } + __LOG( "CUPnPXMLParser::SetAttributesL - End" ); + } + +// -------------------------------------------------------------------------- +// CUPnPXMLParser::SetValueToElementL +// See upnpxmlparser.h +// -------------------------------------------------------------------------- +void CUPnPXMLParser::SetValueToElementL( CUpnpObject& aItem, + const TDesC8& aValue ) + { + __LOG( "CUPnPXMLParser::SetValueToElementL()" ); + + if( iTitle ) + { + __LOG( "SetValueToElementL() - title element" ); + aItem.SetTitleL( aValue ); + iTitle = EFalse; + } + else if( iObjectClass ) + { + __LOG( "SetValueToElementL() - objectclass element" ); + aItem.SetObjectClassL( aValue ); + iObjectClass = EFalse; + } + // See if it's the res-element + else if( iNewElement && // NULL Check + iNewElement->Name().Compare( KContentURI ) == KErrNone ) + { + __LOG( "SetValueToElementL() - res element" ); + + // Check that uri is absolute + if( UpnpCdsResElementUtility::IsUriAbsolute( aValue ) ) + { + __LOG( "valid res-element" ); + iNewElement->SetValueL( aValue ); + aItem.AddElementL( iNewElement ); // Ownership is transferred + iNewElement = NULL; + } + else + { + // if CreateObjectResponse, there is importuri + // no need to check res-element + TInt found = EFalse; + RUPnPAttributesArray elArray = iNewElement->GetAttributes(); + TInt count = elArray.Count(); + for( TInt i = 0; i < count; i++ ) + { + if( elArray[ i ]->Name() == KImportUri ) + { + i = count; + found = ETrue; + __LOG( "SetValueToElementL() - ImportUri found" ); + } + } + + if( found ) + { + __LOG( "no res-element but import uri found" ); + iNewElement->SetValueL( KNullDesC8 ); + aItem.AddElementL( iNewElement ); // Ownership is transferred + iNewElement = NULL; + } + else + { + __LOG( "invalid res-element" ); + delete iNewElement; + iNewElement = NULL; + } + } + + } + else + { + __LOG( "SetValueToElementL() - unknown element" ); + if( iNewElement ) + { + // Check for empty values + if( aValue == KNullDesC8 || aValue == KSpace ) + { + // Do not add empty values + delete iNewElement; iNewElement = NULL; + } + else + { + iNewElement->SetValueL( aValue ); + aItem.AddElementL( iNewElement ); // Ownership is transferred + iNewElement = NULL; + } + } + } + + __LOG( "CUPnPXMLParser::SetValueToElementL() End" ); + } + + +// -------------------------------------------------------------------------- +// CUPnPXMLParser::SetAttributesL +// See upnpxmlparser.h +// -------------------------------------------------------------------------- +void CUPnPXMLParser::SetAttributesL( const RAttributeArray& aAttributes ) + { + __LOG( "CUPnPXMLParser::SetAttributesL" ); + + RAttribute attribute; + TInt count = aAttributes.Count(); + for ( TInt i = 0; i < count ; i++ ) + { + attribute = aAttributes[i]; + const TDesC8& name = attribute.Attribute().LocalName().DesC(); + CUpnpAttribute* att = CUpnpAttribute::NewLC(); + att->SetNameL( name ); + att->SetValueL( attribute.Value().DesC() ); + __ASSERTD( iNewElement, __FILE__, __LINE__ ); + iNewElement->AddAttributeL( att ); + CleanupStack::Pop( att ); + } + __LOG( "CUPnPXMLParser::SetAttributesL End" ); + } + +// end of file +