codhandler/codeng/src/DdParser.cpp
changeset 0 dd21522fd290
child 25 0ed94ceaa377
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/codhandler/codeng/src/DdParser.cpp	Mon Mar 30 12:54:55 2009 +0300
@@ -0,0 +1,1433 @@
+/*
+* Copyright (c) 2002 Nokia Corporation and/or its subsidiary(-ies).
+* All rights reserved.
+* This component and the accompanying materials are made available
+* under the terms of the License "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: 
+*      Implementation of class TDdParser.   
+*      
+*
+*/
+
+
+// INCLUDE FILES
+
+#include "DdParser.h"
+#include "CodData.h"
+#include "CodError.h"
+#include "CodPanic.h"
+#include "CodLogger.h"
+#include "NwUtil.h"
+#include "DdDummyDict.h"
+#include "HttpDownloadData.h"
+#include <nw_dom_document.h>
+#include <utf.h>
+
+// ================= CONSTANTS =======================
+
+// Attribute names.
+_LIT( KDdName, "name" );                        ///< name.
+_LIT( KDdVendor, "vendor" );                    ///< vendor.
+_LIT( KDdDescription, "description" );          ///< description.
+_LIT( KDdUrl, "objectURI" );                    ///< objectURI.
+_LIT( KDdSize, "size" );                        ///< size.
+_LIT( KDdType, "type" );                        ///< type.
+_LIT( KDdInstallNotify, "installNotifyURI" );   ///< installNotifyURI.
+_LIT( KDdNextUrl, "nextURL" );                  ///< nextURL.
+_LIT( KDdInfoUrl, "infoURL" );                  ///< infoURL.
+_LIT( KDdIcon, "iconURI" );                     ///< iconURI.
+_LIT( KDdVersion, "DDVersion" );                ///< DDVersion.
+_LIT( KDdMedia, "media" );                      ///< media.
+// Attribute names for OMA v2 
+_LIT( KDdProduct, "product" );                  ///< media.
+_LIT( KDdMediaObject, "mediaObject" );          ///< mediaObject.
+_LIT( KDdMeta, "meta" );                        ///< meta.
+_LIT( KDdProgressiveDl, "progressiveDownloadFlag" );    ///< progressiveDownloadFlag.
+_LIT( KDdLicense, "license" );                  ///< license.
+_LIT( KDdOrder, "order" );                      ///< order.
+_LIT( KDdSuppressUserConfirmation, "suppressUserConfirmation" ); ///< suppressUserConfirmation.
+_LIT( KDdServer, "server" );                    ///< server.
+_LIT( KDdText, "text" );						///< text.
+_LIT( KDdTrue, "true" );                        ///< true.
+_LIT( KDdFalse, "false" );                      ///< false.
+_LIT( KDdAlways, "Always" );                    ///< Always.
+_LIT( KDdUserConfirmStepOnly, "UserConfirmaStepOnly" );  ///< UserConfirmStepOnly.
+_LIT( KDdNever, "Never" );                      ///< Never.
+_LIT( KDdPost, "post" );                        ///< post.
+_LIT( KDdAny, "any" );                          ///< any.
+_LIT( KDdUpdatedDDURI, "updatedDDURI" );//updatedDDURI
+
+
+#define INDENT_SPACE 2
+
+// ================= MEMBER FUNCTIONS =======================
+
+// ---------------------------------------------------------
+// TDdParser::ParseL()
+// ---------------------------------------------------------
+//
+void TDdParser::ParseL( const TDesC& aBuf, CCodData& aData, const TBool aIsDd2, TBool& aIsLicenseTag )
+    {
+    CLOG(( EParse, 2, _L("-> TDdParser::ParseL") ));
+    CDUMP(( EParse, 2, _S("Buf:"), _S("    "), \
+        (const TUint8*)aBuf.Ptr(), aBuf.Size() ));
+    iError = KErrNone;
+    iData = &aData;
+    // XML Parser expects the buffer contain a BOM and be in
+    // network byte order (this is hard-coded into cXmlParser).
+    // We already have the buffer converted to UCS-2, native byte order, BOM
+    // removed, and this cannot be changed without changing API.
+    // So we have to re-add BOM and convert the buffer back to network byte
+    // order. This is an annoying a waste, luckily a DD file is small
+    // enough not to be significant.
+    HBufC* buf = HBufC::NewLC( aBuf.Length() + 1 );
+    buf->Des().Append( 0xFFFE );    // Add BOM, little endian as aBuf.
+    buf->Des().Append( aBuf );      // Append buffer.
+    // Now turn the whole buffer big-endian.
+    TUint8* ptr = (TUint8*)buf->Ptr();
+    for ( TInt i = 0; i < buf->Size(); i += 2 )
+        {
+        TUint8 tmp = ptr[i];
+        ptr[i] = ptr[i + 1];
+        ptr[i + 1] = tmp;
+        }
+    NW_WBXML_Dictionary_t* dictArray[ 1 ] = 
+        { (NW_WBXML_Dictionary_t*)&NW_DdDummy_WBXMLDictionary };
+    RNwWbxmlDictionary wbxmlDict;
+    User::LeaveIfError( wbxmlDict.Initialize( 1, dictArray ) );
+    CleanupClosePushL<RNwWbxmlDictionary>( wbxmlDict );
+
+    NW_TinyDom_Handle_t domHandle;
+    NW_Status_t stat;
+    CNwDomDocumentNode* docNode = new (ELeave) CNwDomDocumentNode();
+    CleanupStack::PushL( docNode );
+    docNode->iDocNode = CXML_DOM_DocumentNode_BuildTree
+        ( 
+        &domHandle, 
+        (NW_Byte*)buf->Ptr(), 
+        (NW_Int32)buf->Size(), 
+        /*encoded=*/NW_FALSE, 
+        /*publicID=*/NW_DdDummy_PublicId, 
+        /*extTNotStringTable=*/NW_FALSE,
+        &stat
+        );
+    LeaveIfNwErrorL( stat );
+    User::LeaveIfNull( docNode->iDocNode ); // Safety code.
+    if (!aIsDd2)
+	{
+	  DocNodeL( docNode->iDocNode );
+	}
+    else
+	{
+	  iIsLicenseTag = EFalse;
+	  ParseDd2DocNodeL( docNode->iDocNode );
+	}
+    CleanupStack::PopAndDestroy( 3, buf );  // docNode, close wbxmlDict, buf
+
+#ifdef __TEST_COD_LOG
+    TPtrC ptr16;
+    TPtrC8 ptr8;
+    CLOG(( EParse, 3, _L("TCodParser::ParseL data:") ));
+    ptr16.Set( aData.Name() );
+    CLOG(( EParse, 3, _L("  Name<%S>"), &ptr16 ));
+    ptr16.Set( aData.Vendor() );
+    CLOG(( EParse, 3, _L("  Vendor<%S>"), &ptr16 ));
+    ptr16.Set( aData.Description() );
+    CLOG(( EParse, 3, _L("  Desc<%S>"), &ptr16 ));
+    CLOG(( EParse, 3, _L("  Size(%d)"), aData.Size() ));
+    ptr8.Set( aData.InstallNotify() );
+    CLOG(( EParse, 3, _L8("  InstNotif<%S>"), &ptr8 ));
+    ptr8.Set( aData.NextUrl() );
+    CLOG(( EParse, 3, _L8("  NextUrl<%S>"), &ptr8 ));
+    ptr8.Set( aData.NextUrlAtError() );
+    CLOG(( EParse, 3, _L8("  NextUrlAtErr<%S>"), &ptr8 ));
+    ptr8.Set( aData.InfoUrl() );
+    CLOG(( EParse, 3, _L8("  InfoUrl<%S>"), &ptr8 ));
+    ptr16.Set( aData.Price() );
+    CLOG(( EParse, 3, _L("  Price<%S>"), &ptr16 ));
+    ptr8.Set( aData.Icon() );
+    CLOG(( EParse, 3, _L8("  Icon<%S>"), &ptr8 ));
+
+//TODO add logs for OMA 2
+#endif /* def __TEST_COD_LOG */
+	
+	//If there are no media objects present to download, 
+    if( !iData->Count() )
+    	{
+    	User::Leave( KErrCodInvalidDescriptor );	
+    	}
+    	
+    // NULL data for clarity. These are never used later, but don't keep
+    // pointers to objects which are out of reach.
+    iData = NULL;
+    User::LeaveIfError( iError );
+    aIsLicenseTag = iIsLicenseTag;
+    CLOG(( EParse, 2, _L("<- TDdParser::ParseL") ));
+    }
+
+// ---------------------------------------------------------
+// TDdParser::DocNodeL()
+// ---------------------------------------------------------
+//
+void TDdParser::DocNodeL( NW_DOM_DocumentNode_t* aDocNode )
+    {
+    CLOG(( EParse, 2, _L("-> TDdParser::DocNodeL") ));
+    __ASSERT_DEBUG( aDocNode, CodPanic( ECodInternal ) );
+    // Validity checking of root element (media).
+    NW_DOM_ElementNode_t* elmt = 
+        NW_DOM_DocumentNode_getDocumentElement( aDocNode );
+    if ( !elmt || NW_DOM_Node_getNodeType( elmt ) != NW_DOM_ELEMENT_NODE )
+        {
+        User::Leave( KErrCodInvalidDescriptor );
+        }
+    NW_String_t str;
+    LeaveIfNwErrorL( NW_DOM_Node_getNodeName( elmt, &str ) );
+    CleanupNwStringStoragePushL( &str );
+    iEncoding = NW_DOM_DocumentNode_getCharacterEncoding( aDocNode );
+    NW_Ucs2* name;
+    LeaveIfNwErrorL( NW_String_stringToUCS2Char( &str, iEncoding, &name ) );
+    CleanupNwUcs2PushL( name );
+    if ( TPtrC( name ).Compare( KDdMedia() ) )
+        {
+        User::Leave( KErrCodInvalidDescriptor );
+        }
+    CleanupStack::PopAndDestroy( 2 );   // clean up name, str->storage
+
+    // Process child element nodes.
+    NW_DOM_Node_t* node = NW_DOM_Node_getFirstChild( elmt );
+    CMediaObjectData *mediaObject = CMediaObjectData::NewL();
+    while ( node )
+        {
+        if ( NW_DOM_Node_getNodeType( node ) == NW_DOM_ELEMENT_NODE )
+            {
+            ElementNodeL( STATIC_CAST( NW_DOM_ElementNode_t*, node ), mediaObject );
+            }
+        node = NW_DOM_Node_getNextSibling( node );
+        }
+	iData->AppendMediaObjectL( mediaObject );        
+    CLOG(( EParse, 2, _L("<- TDdParser::DocNodeL") ));
+    }
+
+// ---------------------------------------------------------
+// TDdParser::ParseDd2DocNodeL()
+// ---------------------------------------------------------
+//
+void TDdParser::ParseDd2DocNodeL( NW_DOM_DocumentNode_t* aDocNode )
+{
+    CLOG(( EParse, 2, _L("-> TDdParser::ParseDd2DocNodeL") ));
+    __ASSERT_DEBUG( aDocNode, CodPanic( ECodInternal ) );
+    // Validity checking of root element (media).
+    NW_DOM_ElementNode_t* elmt = 
+        NW_DOM_DocumentNode_getDocumentElement( aDocNode );
+    if ( !elmt || NW_DOM_Node_getNodeType( elmt ) != NW_DOM_ELEMENT_NODE )
+        {
+        User::Leave( KErrCodInvalidDescriptor );
+        }
+    NW_String_t str;
+    LeaveIfNwErrorL( NW_DOM_Node_getNodeName( elmt, &str ) );
+    CleanupNwStringStoragePushL( &str );
+    iEncoding = NW_DOM_DocumentNode_getCharacterEncoding( aDocNode );
+    NW_Ucs2* name;
+    LeaveIfNwErrorL( NW_String_stringToUCS2Char( &str, iEncoding, &name ) );
+    CleanupNwUcs2PushL( name );
+    if ( TPtrC( name ).Compare( KDdMedia() ) )
+        {
+        User::Leave( KErrCodInvalidDescriptor );
+        }
+    CleanupStack::PopAndDestroy( 2 );   // clean up name, str->storage
+    ParseMediaElementsL( elmt );
+    CLOG(( EParse, 2, _L("<- TDdParser::ParseDd2DocNodeL") ));
+}
+
+// ---------------------------------------------------------
+// TDdParser::ParseMediaElementsL()
+// ---------------------------------------------------------
+//
+void TDdParser::ParseMediaElementsL( NW_DOM_ElementNode_t* aElement)
+{
+    CLOG(( EParse, 2, _L("-> TDdParser::ParseMediaElementsL") ));
+
+    // Process child elements for Media Object
+    NW_DOM_Node_t* node = NW_DOM_Node_getFirstChild( aElement );
+    while ( node )
+        {
+        if ( NW_DOM_Node_getNodeType( node ) == NW_DOM_ELEMENT_NODE )
+            {
+            MediaElementNodeL( STATIC_CAST( NW_DOM_ElementNode_t*, node ) );
+            }
+        node = NW_DOM_Node_getNextSibling( node );
+        }
+
+	// Get Attributs for this node
+    NW_Status_t stat = NW_STAT_SUCCESS;
+
+    if ( NW_DOM_ElementNode_hasAttributes( aElement ) )
+        {
+
+        NW_DOM_AttributeListIterator_t attrIter;
+        stat = NW_DOM_ElementNode_getAttributeListIterator
+                             ( aElement, &attrIter );
+
+        User::LeaveIfError( NwStatus2Error( stat ) );
+        NW_DOM_AttributeHandle_t attrHandle;
+        while( NW_DOM_AttributeListIterator_getNextAttribute( &attrIter, &attrHandle ) == NW_STAT_WBXML_ITERATE_MORE )
+            {
+            ParseNodeAttributesL( &attrHandle );
+            }
+        }
+
+	CLOG(( EParse, 2, _L("<- TDdParser::ParseMediaElementsL") ));
+}
+
+// ---------------------------------------------------------
+// TDdParser::ParseProductElementsL()
+// ---------------------------------------------------------
+//
+void TDdParser::ParseProductElementsL( NW_DOM_ElementNode_t* aElement)
+{
+    CLOG(( EParse, 2, _L("-> TDdParser::ParseProductElementsL") ));
+    // Process child elements for Product  Object
+    NW_DOM_Node_t* node = NW_DOM_Node_getFirstChild( aElement );
+    while ( node )
+        {
+        if ( NW_DOM_Node_getNodeType( node ) == NW_DOM_ELEMENT_NODE )
+            {
+            ProductElementNodeL( STATIC_CAST( NW_DOM_ElementNode_t*, node ) );
+            }
+        node = NW_DOM_Node_getNextSibling( node );
+        }
+	CLOG(( EParse, 2, _L("<- TDdParser::ParseProductElementsL") ));
+}
+
+// ---------------------------------------------------------
+// TDdParser::ParseMediaObjectElementsL()
+// ---------------------------------------------------------
+//
+void TDdParser::ParseMediaObjectElementsL( NW_DOM_ElementNode_t* aElement)
+{
+    CLOG(( EParse, 2, _L("-> TDdParser::ParseMediaObjectElementsL") ));
+    //Create a media object and append it to Cod Data array
+    CMediaObjectData *mediaObject = CMediaObjectData::NewL();
+
+    // Process child elements for MediaObject
+    NW_DOM_Node_t* node = NW_DOM_Node_getFirstChild( aElement );
+    while ( node )
+        {
+        if ( NW_DOM_Node_getNodeType( node ) == NW_DOM_ELEMENT_NODE )
+            {
+            MediaObjElementNodeL( STATIC_CAST( NW_DOM_ElementNode_t*, node), mediaObject );
+            }
+        node = NW_DOM_Node_getNextSibling( node );
+        }
+
+    if(!mediaObject->Name().Compare(KNullDesC) && mediaObject->Url().Compare(KNullDesC8))
+        {
+        ParseNameFromUrlL( mediaObject );
+        }
+    iData->AppendMediaObjectL( mediaObject );              
+    
+	CLOG(( EParse, 2, _L("<- TDdParser::ParseMediaObjectElementsL") ));
+}
+
+// ---------------------------------------------------------
+// TDdParser::ParseMetaElementsL()
+// ---------------------------------------------------------
+//
+void TDdParser::ParseMetaElementsL( NW_DOM_ElementNode_t* aElement)
+{
+	CLOG(( EParse, 2, _L("-> TDdParser::ParseMetaElementsL") ));
+    // Process child elements foe Media Object
+    NW_DOM_Node_t* node = NW_DOM_Node_getFirstChild( aElement );
+    while ( node )
+        {
+        if ( NW_DOM_Node_getNodeType( node ) == NW_DOM_ELEMENT_NODE )
+            {
+            MetaElementNodeL( STATIC_CAST( NW_DOM_ElementNode_t*, node ) );
+            }
+        node = NW_DOM_Node_getNextSibling( node );
+        }
+	CLOG(( EParse, 2, _L("<- TDdParser::ParseMetaElementsL") ));
+}
+
+// ---------------------------------------------------------
+// TDdParser::ParseMetaElementsL()
+// ---------------------------------------------------------
+//
+void TDdParser::ParseMetaElementsL( NW_DOM_ElementNode_t* aElement, CMediaObjectData *& aMediaObject )
+{
+	CLOG(( EParse, 2, _L("-> TDdParser::ParseMetaElementsL") ));
+    // Process child elements foe Media Object
+    NW_DOM_Node_t* node = NW_DOM_Node_getFirstChild( aElement );
+    while ( node )
+        {
+        if ( NW_DOM_Node_getNodeType( node ) == NW_DOM_ELEMENT_NODE )
+            {
+            MetaElementNodeL( STATIC_CAST( NW_DOM_ElementNode_t*, node ), aMediaObject );
+            }
+        node = NW_DOM_Node_getNextSibling( node );
+        }
+	CLOG(( EParse, 2, _L("<- TDdParser::ParseMetaElementsL") ));
+}
+
+// ---------------------------------------------------------
+// TDdParser::ParseObjectUriElementsL()
+// ---------------------------------------------------------
+//
+void TDdParser::ParseObjectUriElementsL( NW_DOM_ElementNode_t* aElement, CMediaObjectData *& aMediaObject )
+{
+	CLOG(( EParse, 2, _L("-> TDdParser::ParseObjectUriElementsL") ));
+    // Process child elements for Media Object
+    NW_DOM_Node_t* node = NW_DOM_Node_getFirstChild( aElement );
+    while ( node )
+        {
+        if ( NW_DOM_Node_getNodeType( node ) == NW_DOM_ELEMENT_NODE )
+            {
+            ObjUriElementNodeL( STATIC_CAST( NW_DOM_ElementNode_t*, node ), aMediaObject );
+            }
+        node = NW_DOM_Node_getNextSibling( node );
+        }
+	CLOG(( EParse, 2, _L("<- TDdParser::ParseObjectUriElementsL") ));
+}
+
+// ---------------------------------------------------------
+// TDdParser::MediaElementNodeL()
+// ---------------------------------------------------------
+//
+void TDdParser::MediaElementNodeL( NW_DOM_ElementNode_t* aElmtNode )
+    {
+    CLOG(( EParse, 2, _L("-> TDdParser::MediaElementNodeL") ));
+    __ASSERT_DEBUG( aElmtNode, CodPanic( ECodInternal ) );
+
+    NW_String_t str;
+    LeaveIfNwErrorL( NW_DOM_Node_getNodeName( aElmtNode, &str ) );
+    CleanupNwStringStoragePushL( &str );
+    NW_Ucs2* ucs2;
+    LeaveIfNwErrorL( NW_String_stringToUCS2Char( &str, iEncoding, &ucs2 ) );
+    CleanupNwUcs2PushL( ucs2 );
+    TPtrC attrName( ucs2 );
+    TDdAttr attr = MediaAttribute( attrName );
+    CLOG(( EParse, 4, _L("  attribute <%S> (%d)"), &attrName, attr ));
+    CleanupStack::PopAndDestroy( 2 );   // Clean up ucs2, str->storage
+	if ( attr == EDdProduct )
+	{	
+	    if( iData && !iData->Count() )
+	        {
+    		ParseProductElementsL(aElmtNode);
+	        }
+		return;
+	}
+    if ( attr != EDdUnknownAttr )   // Unknown attribute is ignored.
+        {
+        ucs2 = PcDataLC( aElmtNode );
+        if ( ucs2 )
+            {
+            SetMediaAttrL( attr, TPtrC( ucs2 ) );
+            }
+        CleanupStack::PopAndDestroy();  // Clean up ucs2.
+        }
+    CLOG(( EParse, 2, _L("<- TDdParser::MediaElementNodeL") ));
+    }
+
+// ---------------------------------------------------------
+// TDdParser::ParseNodeAttributesL()
+// ---------------------------------------------------------
+//
+void TDdParser::ParseNodeAttributesL( NW_DOM_AttributeHandle_t* aAttrHandle )
+{
+	CLOG(( EParse, 2, _L("-> TDdParser::ParseNodeAttributesL") ));
+    NW_Status_t stat = NW_STAT_SUCCESS;
+    NW_String_t str;
+    // Get the name of the attribute.
+    stat = NW_DOM_AttributeHandle_getName( aAttrHandle, &str );
+    User::LeaveIfError( NwStatus2Error( stat ) );
+
+    CleanupNwStringStoragePushL( &str );
+    NW_Ucs2* ucs2;
+    LeaveIfNwErrorL( NW_String_stringToUCS2Char( &str, iEncoding, &ucs2 ) );
+    CleanupNwUcs2PushL( ucs2 );
+
+    TPtrC attrName( ucs2 );
+    TDdAttr attr = DdVersionAttribute( attrName );
+	CleanupStack::PopAndDestroy( 2 );   // Clean up ucs2, str->storage
+    if ( attr != EDdUnknownAttr )   // Unknown attribute is ignored.
+		{
+        LeaveIfNwErrorL(NW_DOM_AttributeHandle_getValue(aAttrHandle, &str) );
+        LeaveIfNwErrorL( NW_String_stringToUCS2Char(&str, iEncoding, &ucs2) );
+        if ( ucs2 )
+            {
+			if ( (attr == EDdVersion))
+				{
+				iData->SetVersionL( TPtrC ( ucs2 ));
+				}
+            }
+        }
+    CLOG(( EParse, 2, _L("<- TDdParser::ParseNodeAttributesL") ));
+}
+
+// ---------------------------------------------------------
+// TDdParser::ObjUriElementNodeL()
+// ---------------------------------------------------------
+//
+void TDdParser::ObjUriElementNodeL( NW_DOM_ElementNode_t* aElmtNode, CMediaObjectData *& aMediaObject )
+    {
+	CLOG(( EParse, 2, _L("-> TDdParser::ObjUriElementNodeL") ));
+    __ASSERT_DEBUG( aElmtNode, CodPanic( ECodInternal ) );
+    NW_String_t str;
+    LeaveIfNwErrorL( NW_DOM_Node_getNodeName( aElmtNode, &str ) );
+    CleanupNwStringStoragePushL( &str );
+    NW_Ucs2* ucs2;
+    LeaveIfNwErrorL( NW_String_stringToUCS2Char( &str, iEncoding, &ucs2 ) );
+    CleanupNwUcs2PushL( ucs2 );
+
+    TPtrC attrName( ucs2 );
+    TDdAttr attr = ObjUriAttribute( attrName );
+	CleanupStack::PopAndDestroy( 2 );   // Clean up ucs2, str->storage
+	TInt ok( EFalse );
+    if ( attr != EDdUnknownAttr )   // Unknown attribute is ignored.
+		{
+        ucs2 = PcDataLC( aElmtNode );
+        if ( ucs2 )
+            {
+			/* composite objects (multiple server elements) are not supported in 3.2
+			   So, it takes last ObjectUri
+			*/
+			if ( (attr == EDdUrl))
+				{
+				ok = aMediaObject->SetUrlL( TPtrC ( ucs2 ));
+				}
+            }
+        CleanupStack::PopAndDestroy();  // Clean up ucs2.
+        }
+		if ( !ok )
+			{
+			Error( KErrCodInvalidDescriptor );
+			}
+		CLOG(( EParse, 2, _L("<- TDdParser::ObjUriElementNodeL") ));
+    }
+
+// ---------------------------------------------------------
+// TDdParser::MediaObjElementNodeL()
+// ---------------------------------------------------------
+//
+void TDdParser::MediaObjElementNodeL( NW_DOM_ElementNode_t* aElmtNode, CMediaObjectData *& aMediaObject )
+    {
+    CLOG(( EParse, 2, _L("-> TDdParser::MediaObjElementNodeL") ));
+    __ASSERT_DEBUG( aElmtNode, CodPanic( ECodInternal ) );
+    NW_String_t str;
+    LeaveIfNwErrorL( NW_DOM_Node_getNodeName( aElmtNode, &str ) );
+    CleanupNwStringStoragePushL( &str );
+    NW_Ucs2* ucs2;
+    LeaveIfNwErrorL( NW_String_stringToUCS2Char( &str, iEncoding, &ucs2 ) );
+    CleanupNwUcs2PushL( ucs2 );
+    TPtrC attrName( ucs2 );
+    TDdAttr attr = MediaObjAttribute( attrName );
+    CLOG(( EParse, 4, _L("  attribute <%S> (%d)"), &attrName, attr ));
+    CleanupStack::PopAndDestroy( 2 );   // Clean up ucs2, str->storage
+	if ( attr == EDdMeta )
+	{
+		ParseMetaElementsL(aElmtNode, aMediaObject );
+		return;
+	}
+	if ( attr == EDdUrl )
+	{
+		ParseObjectUriElementsL(aElmtNode, aMediaObject );
+		return;
+	}
+    if ( attr != EDdUnknownAttr )   // Unknown attribute is ignored.
+        {
+        ucs2 = PcDataLC( aElmtNode );
+        if ( ucs2 )
+            {
+            SetMediaObjAttrL( attr, TPtrC( ucs2 ), aMediaObject );
+            }
+        CleanupStack::PopAndDestroy();  // Clean up ucs2.
+        }
+    CLOG(( EParse, 2, _L("<- TDdParser::MediaObjElementNodeL") ));
+    }
+
+// ---------------------------------------------------------
+// TDdParser::ProductElementNodeL()
+// ---------------------------------------------------------
+//
+void TDdParser::ProductElementNodeL( NW_DOM_ElementNode_t* aElmtNode )
+    {
+	CLOG(( EParse, 2, _L("-> TDdParser::ProductElementNodeL") ));
+	__ASSERT_DEBUG( aElmtNode, CodPanic( ECodInternal ) );
+	NW_String_t str;
+	LeaveIfNwErrorL( NW_DOM_Node_getNodeName( aElmtNode, &str ) );
+	CleanupNwStringStoragePushL( &str );
+	NW_Ucs2* ucs2;
+	LeaveIfNwErrorL( NW_String_stringToUCS2Char( &str, iEncoding, &ucs2 ) );
+	CleanupNwUcs2PushL( ucs2 );
+	TPtrC attrName( ucs2 );
+	TDdAttr attr = ProductAttribute( attrName );
+	CLOG(( EParse, 4, _L("  attribute <%S> (%d)"), &attrName, attr ));
+	CleanupStack::PopAndDestroy( 2 );   // Clean up ucs2, str->storage
+	if ( attr == EDdMeta )
+	{
+		ParseMetaElementsL(aElmtNode);
+	}
+	if ( attr == EDdMediaObject )
+	{
+		ParseMediaObjectElementsL(aElmtNode);
+	}
+	CLOG(( EParse, 2, _L("<- TDdParser::ProductElementNodeL") ));
+    }
+
+// ---------------------------------------------------------
+// TDdParser::MetaElementNodeL()
+// ---------------------------------------------------------
+//
+void TDdParser::MetaElementNodeL( NW_DOM_ElementNode_t* aElmtNode )
+    {
+    CLOG(( EParse, 2, _L("-> TDdParser::MetaElementNodeL") ));
+    __ASSERT_DEBUG( aElmtNode, CodPanic( ECodInternal ) );
+    NW_String_t str;
+    LeaveIfNwErrorL( NW_DOM_Node_getNodeName( aElmtNode, &str ) );
+    CleanupNwStringStoragePushL( &str );
+    NW_Ucs2* ucs2;
+    LeaveIfNwErrorL( NW_String_stringToUCS2Char( &str, iEncoding, &ucs2 ) );
+    CleanupNwUcs2PushL( ucs2 );
+    TPtrC attrName( ucs2 );
+    TDdAttr attr = MetaAttribute( attrName );
+    CLOG(( EParse, 4, _L("  attribute <%S> (%d)"), &attrName, attr ));
+    CleanupStack::PopAndDestroy( 2 );   // Clean up ucs2, str->storage
+	if ( attr == EDdLicense )
+	{
+		iIsLicenseTag = ETrue;
+		return;
+	}
+    if ( attr != EDdUnknownAttr )   // Unknown attribute is ignored.
+        {
+        ucs2 = PcDataLC( aElmtNode );
+        if ( ucs2 )
+            {
+            SetMetaAttrL( attr, TPtrC( ucs2 ) );
+            }
+        CleanupStack::PopAndDestroy();  // Clean up ucs2.
+        }
+    CLOG(( EParse, 2, _L("<- TDdParser::MetaElementNodeL") ));
+    }
+
+// ---------------------------------------------------------
+// TDdParser::MetaElementNodeL()
+// ---------------------------------------------------------
+//
+void TDdParser::MetaElementNodeL( NW_DOM_ElementNode_t* aElmtNode, CMediaObjectData *& aMediaObject )
+    {
+    CLOG(( EParse, 2, _L("-> TDdParser::MetaElementNodeL") ));
+    __ASSERT_DEBUG( aElmtNode, CodPanic( ECodInternal ) );
+    NW_String_t str;
+    LeaveIfNwErrorL( NW_DOM_Node_getNodeName( aElmtNode, &str ) );
+    CleanupNwStringStoragePushL( &str );
+    NW_Ucs2* ucs2;
+    LeaveIfNwErrorL( NW_String_stringToUCS2Char( &str, iEncoding, &ucs2 ) );
+    CleanupNwUcs2PushL( ucs2 );
+    TPtrC attrName( ucs2 );
+    TDdAttr attr = MetaAttribute( attrName );
+    CLOG(( EParse, 4, _L("  attribute <%S> (%d)"), &attrName, attr ));
+    CleanupStack::PopAndDestroy( 2 );   // Clean up ucs2, str->storage
+	if ( attr == EDdLicense )
+	{
+		iIsLicenseTag = ETrue;
+		return;
+	}
+    if ( attr != EDdUnknownAttr )   // Unknown attribute is ignored.
+        {
+        ucs2 = PcDataLC( aElmtNode );
+        if ( ucs2 )
+            {
+            SetMetaAttrL( attr, TPtrC( ucs2 ), aMediaObject );
+            }
+        CleanupStack::PopAndDestroy();  // Clean up ucs2.
+        }
+    CLOG(( EParse, 2, _L("<- TDdParser::MetaElementNodeL") ));
+    }// ---------------------------------------------------------
+// TDdParser::ElementNodeL()
+// ---------------------------------------------------------
+//
+void TDdParser::ElementNodeL( NW_DOM_ElementNode_t* aElmtNode, CMediaObjectData *& aMediaObject )
+    {
+    CLOG(( EParse, 2, _L("-> TDdParser::ElementNodeL") ));
+    __ASSERT_DEBUG( aElmtNode, CodPanic( ECodInternal ) );
+    NW_String_t str;
+    LeaveIfNwErrorL( NW_DOM_Node_getNodeName( aElmtNode, &str ) );
+    CleanupNwStringStoragePushL( &str );
+    NW_Ucs2* ucs2;
+    LeaveIfNwErrorL( NW_String_stringToUCS2Char( &str, iEncoding, &ucs2 ) );
+    CleanupNwUcs2PushL( ucs2 );
+    TPtrC attrName( ucs2 );
+    TDdAttr attr = Attribute( attrName );
+    CLOG(( EParse, 4, _L("  attribute <%S> (%d)"), &attrName, attr ));
+    CleanupStack::PopAndDestroy( 2 );   // Clean up ucs2, str->storage
+    if ( attr != EDdUnknownAttr )   // Unknown attribute is ignored.
+        {
+        ucs2 = PcDataLC( aElmtNode );
+        if ( ucs2 )
+            {
+            SetAttrL( attr, TPtrC( ucs2 ), aMediaObject );
+            }
+        CleanupStack::PopAndDestroy();  // Clean up ucs2.
+        }
+    CLOG(( EParse, 2, _L("<- TDdParser::ElementNodeL") ));
+    }
+
+// ---------------------------------------------------------
+// TDdParser::PcDataLC()
+// ---------------------------------------------------------
+//
+NW_Ucs2* TDdParser::PcDataLC( NW_DOM_ElementNode_t* aElmtNode )
+    {
+    __ASSERT_DEBUG( aElmtNode, CodPanic( ECodInternal ) );
+    NW_Ucs2* ucs2 = NULL;
+    NW_DOM_TextNode_t* textNode = NW_DOM_Node_getFirstChild( aElmtNode );
+    if ( textNode && NW_DOM_Node_getNodeType( textNode ) == NW_DOM_TEXT_NODE )
+        {
+        NW_String_t str;
+        LeaveIfNwErrorL( NW_DOM_TextNode_getData( textNode, &str ) );
+        CleanupNwStringStoragePushL( &str );
+        LeaveIfNwErrorL
+            ( NW_String_stringToUCS2Char( &str, iEncoding, &ucs2 ) );
+        CleanupStack::PopAndDestroy();  // Clean up str->storage.
+        CleanupNwUcs2PushL( ucs2 );
+        }
+    if ( !ucs2 )
+        {
+        // Push the NULL.
+        CleanupStack::PushL( ucs2 );
+        }
+    return ucs2;
+    }
+
+// ---------------------------------------------------------
+// TDdParser::GetAttrValueLC()
+// ---------------------------------------------------------
+//
+/*
+NW_Ucs2* TDdParser::GetAttrValueLC( NW_DOM_ElementNode_t* aElmtNode, NW_DOM_AttributeHandle_t* aAttrHandle )
+    {
+    __ASSERT_DEBUG( aElmtNode, CodPanic( ECodInternal ) );
+    NW_Ucs2* ucs2 = NULL;
+    NW_DOM_TextNode_t* textNode = NW_DOM_Node_getFirstChild( aElmtNode );
+    if ( textNode && NW_DOM_Node_getNodeType( textNode ) == NW_DOM_TEXT_NODE )
+        {
+        NW_String_t str;
+        LeaveIfNwErrorL( NW_DOM_TextNode_getData( textNode, &str ) );
+        CleanupNwStringStoragePushL( &str );
+        LeaveIfNwErrorL
+            ( NW_String_stringToUCS2Char( &str, iEncoding, &ucs2 ) );
+        CleanupStack::PopAndDestroy();  // Clean up str->storage.
+        CleanupNwUcs2PushL( ucs2 );
+        }
+    if ( !ucs2 )
+        {
+        // Push the NULL.
+        CleanupStack::PushL( ucs2 );
+        }
+    return ucs2;
+    }
+*/
+// ---------------------------------------------------------
+// TDdParser::Attribute() // for OMA v1
+// ---------------------------------------------------------
+//
+TDdParser::TDdAttr TDdParser::Attribute( const TDesC& aAttrName ) const
+    {
+    TDdAttr attr = EDdUnknownAttr;
+    if ( !aAttrName.Compare( KDdName ) )
+        {
+        attr = EDdName;
+        }
+    else if ( !aAttrName.Compare( KDdVendor ) )
+        {
+        attr = EDdVendor;
+        }
+    else if ( !aAttrName.Compare( KDdDescription ) )
+        {
+        attr = EDdDescription;
+        }
+    else if ( !aAttrName.Compare( KDdUrl ) )
+        {
+        attr = EDdUrl;
+        }
+    else if ( !aAttrName.Compare( KDdSize ) )
+        {
+        attr = EDdSize;
+        }
+    else if ( !aAttrName.Compare( KDdType ) )
+        {
+        attr = EDdType;
+        }
+    else if ( !aAttrName.Compare( KDdInstallNotify ) )
+        {
+        attr = EDdInstallNotify;
+        }
+    else if ( !aAttrName.Compare( KDdNextUrl ) )
+        {
+        attr = EDdNextUrl;
+        }
+    else if ( !aAttrName.Compare( KDdInfoUrl ) )
+        {
+        attr = EDdInfoUrl;
+        }
+    else if ( !aAttrName.Compare( KDdIcon ) )
+        {
+        attr = EDdIcon;
+        }
+    else if ( !aAttrName.Compare( KDdVersion ) )
+        {
+        attr = EDdVersion;
+        }
+    return attr;
+    }
+
+// ---------------------------------------------------------
+// TDdParser::MediaAttribute() // for OMA v2
+// ---------------------------------------------------------
+//
+TDdParser::TDdAttr TDdParser::MediaAttribute( const TDesC& aAttrName ) const
+    {
+    TDdAttr attr = EDdUnknownAttr;
+
+	if ( !aAttrName.Compare( KDdVersion ) )
+        {
+        attr = EDdVersion;
+        }
+    else if ( !aAttrName.Compare( KDdVendor ) )
+        {
+        attr = EDdVendor;
+        }
+    else if ( !aAttrName.Compare( KDdName ) )
+        {
+        attr = EDdName;
+        }
+    else if ( !aAttrName.Compare( KDdNextUrl ) )
+        {
+        attr = EDdNextUrl;
+        }
+    else if ( !aAttrName.Compare( KDdProduct ) )
+        {
+        attr = EDdProduct;
+        }
+    else if ( !aAttrName.Compare( KDdUpdatedDDURI ) )
+        {
+        attr = EDdUpdatedDDURI;
+        }        
+    return attr;
+    }
+
+// ---------------------------------------------------------
+// TDdParser::MediaObjAttribute() // for OMA v2
+// ---------------------------------------------------------
+//
+TDdParser::TDdAttr TDdParser::MediaObjAttribute( const TDesC& aAttrName ) const
+    {
+    TDdAttr attr = EDdUnknownAttr;
+
+	if ( !aAttrName.Compare( KDdUrl ) )
+        {
+        attr = EDdUrl;
+        }
+    else if ( !aAttrName.Compare( KDdSize ) )
+        {
+        attr = EDdSize;
+        }
+    else if ( !aAttrName.Compare( KDdType ) )
+        {
+        attr = EDdType;
+        }
+    else if ( !aAttrName.CompareF( KDdProgressiveDl ) )
+        {
+        attr = EDdProgressiveDl;
+        }
+    else if ( !aAttrName.CompareF( KDdSuppressUserConfirmation ) )
+        {
+        attr = EDdSuppressUserConfirmation;
+        }
+    else if ( !aAttrName.Compare( KDdMeta ) )
+        {
+        attr = EDdMeta;
+        }
+
+    return attr;
+    }
+
+// ---------------------------------------------------------
+// TDdParser::ObjUriAttribute() // for OMA v2
+// ---------------------------------------------------------
+//
+TDdParser::TDdAttr TDdParser::ObjUriAttribute( const TDesC& aAttrName ) const
+    {
+    TDdAttr attr = EDdUnknownAttr;
+
+	if ( !aAttrName.Compare( KDdServer ) )
+        {
+        attr = EDdUrl;
+        }
+    return attr;
+    }
+
+// ---------------------------------------------------------
+// TDdParser::DdVersionAttribute() // for OMA v2
+// ---------------------------------------------------------
+//
+TDdParser::TDdAttr TDdParser::DdVersionAttribute( const TDesC& aAttrName ) const
+    {
+    TDdAttr attr = EDdUnknownAttr;
+
+	if ( !aAttrName.Compare( KDdVersion ) )
+        {
+        attr = EDdVersion;
+        }
+    return attr;
+    }
+
+// ---------------------------------------------------------
+// TDdParser::MetaAttribute() // for OMA v2
+// ---------------------------------------------------------
+//
+TDdParser::TDdAttr TDdParser::MetaAttribute( const TDesC& aAttrName ) const
+    {
+    TDdAttr attr = EDdUnknownAttr;
+    if ( !aAttrName.Compare( KDdName ) )
+        {
+        attr = EDdName;
+        }
+    if ( !aAttrName.Compare( KDdText ) )
+        {
+        attr = EDdText;
+        }
+    else if ( !aAttrName.Compare( KDdDescription ) )
+        {
+        attr = EDdDescription;
+        }
+    else if ( !aAttrName.Compare( KDdInstallNotify ) )
+        {
+        attr = EDdInstallNotify;
+        }
+    else if ( !aAttrName.Compare( KDdLicense ) )
+        {
+        attr = EDdLicense;
+        }
+    else if ( !aAttrName.Compare( KDdOrder ) )
+        {
+        attr = EDdOrder;
+        }
+    return attr;
+    }
+
+// ---------------------------------------------------------
+// TDdParser::ProductAttribute() // for OMA v2
+// ---------------------------------------------------------
+//
+TDdParser::TDdAttr TDdParser::ProductAttribute( const TDesC& aAttrName ) const
+    {
+    TDdAttr attr = EDdUnknownAttr;
+    if ( !aAttrName.Compare( KDdMeta ) )
+        {
+        attr = EDdMeta;
+        }
+    if ( !aAttrName.Compare( KDdMediaObject ) )
+        {
+        attr = EDdMediaObject;
+        }
+    return attr;
+    }
+
+// ---------------------------------------------------------
+// TDdParser::SetAttrL()  // for OMA v1
+// ---------------------------------------------------------
+//
+void TDdParser::SetAttrL( TDdAttr aAttr, const TDesC& aValue, CMediaObjectData *& aMediaObject )
+    {
+    TInt ok( ETrue );
+    switch( aAttr )
+        {
+        case EDdName:
+            {
+            if ( !aMediaObject->Name().Length() )
+                {
+                ok = aMediaObject->SetNameL( aValue );
+                }
+            break;
+            }
+
+        case EDdDescription:
+            {
+            if ( !aMediaObject->Description().Length() )
+                {
+                ok = aMediaObject->SetDescriptionL( aValue );
+                }
+            break;
+            }
+
+        case EDdUrl:
+            {
+            if ( !aMediaObject->Url().Length() )
+                {
+                ok = aMediaObject->SetUrlL( aValue );
+                }
+            break;
+            }
+
+        case EDdSize:
+            {
+            if ( !aMediaObject->Size() )
+                {
+                // Parse as TUint - negative not allowed.
+                TUint size;
+                TLex lex( aValue );
+                if ( !lex.Val( size ) )
+                    {
+                    aMediaObject->SetSize( size );
+                    }
+                else
+                    {
+                    ok = EFalse;
+                    }
+                }
+            break;
+            }
+
+        case EDdType:
+            {
+            ok = aMediaObject->AddTypeL( aValue );
+            break;
+            }
+
+        case EDdInstallNotify:
+            {
+            if ( !aMediaObject->InstallNotify().Length() )
+                {
+                ok = aMediaObject->SetInstallNotifyL( aValue );
+                }
+            break;
+            }
+
+        case EDdInfoUrl:
+            {
+            if ( !aMediaObject->InfoUrl().Length() )
+                {
+                ok = aMediaObject->SetInfoUrlL( aValue );
+                }
+            break;
+            }
+
+        case EDdIcon:
+            {
+            if ( !aMediaObject->Icon().Length() )
+                {
+                ok = aMediaObject->SetIconL( aValue );
+                }
+            break;
+            }
+            
+        case EDdVersion:
+            {
+            if ( !iData->Version().Length() )
+                {
+                ok = iData->SetVersionL( aValue );
+                }
+            break;
+            }
+
+        case EDdNextUrl:
+            {
+            if ( !iData->NextUrl().Length() )
+                {
+                ok = iData->SetNextUrlL( aValue );
+                }
+            break;
+            }
+
+        case EDdVendor:
+            {
+            if ( !iData->Vendor().Length() )
+                {
+                ok = iData->SetVendorL( aValue );
+                }
+            break;
+            }
+                        
+        default:
+            {
+            // Unexpected value.
+            CodPanic( ECodInternal );
+            }
+        }
+    if ( !ok )
+        {
+        Error( KErrCodInvalidDescriptor );
+        }
+    }
+
+
+// ---------------------------------------------------------
+// TDdParser::SetMediaAttrL()
+// ---------------------------------------------------------
+//
+void TDdParser::SetMediaAttrL( TDdAttr aAttr, const TDesC& aValue )
+    {
+    TInt ok( ETrue );
+    switch( aAttr )
+        {
+        case EDdName:
+            {
+            if ( !iData->Name().Length() )
+                {
+                ok = iData->SetNameL( aValue );
+                }
+            break;
+            }
+        case EDdVersion:
+            {
+            if ( !iData->Version().Length() )
+                {
+                ok = iData->SetVersionL( aValue );
+                }
+            break;
+            }
+
+        case EDdVendor:
+            {
+            if ( !iData->Vendor().Length() )
+                {
+                ok = iData->SetVendorL( aValue );
+                }
+            break;
+            }
+
+        case EDdNextUrl:
+            {
+            if ( !iData->NextUrl().Length() )
+                {
+                // Unlike COD, DD has no separate URL-s for success and error
+                // service flow. Since we have a common data structore for
+                // both (which contains separate URLs for those), we fill both
+                // URLs with this value.
+                ok = iData->SetNextUrlL( aValue ) &&
+                     iData->SetNextUrlAtErrorL( aValue );
+                }
+            break;
+            }
+
+        case EDdUpdatedDDURI:
+            {
+            if(!iData->UpdatedDDUriL().Length())
+                {
+                iData->SetUpdatedDDURI( aValue );
+                }
+            
+            break;
+            }
+
+        default:
+            {
+            // Unexpected value.
+            CodPanic( ECodInternal );
+            }
+        }
+    if ( !ok )
+        {
+        Error( KErrCodInvalidDescriptor );
+        }
+    }
+
+// ---------------------------------------------------------
+// TDdParser::SetMediaObjAttrL()
+// ---------------------------------------------------------
+//
+void TDdParser::SetMediaObjAttrL( TDdAttr aAttr, const TDesC& aValue, CMediaObjectData *& aMediaObject )
+    {
+    TInt ok( ETrue );
+    switch( aAttr )
+        {
+        case EDdSize:
+            {
+            if ( !aMediaObject->Size() )
+                {
+                // Parse as TUint - negative not allowed.
+                TUint size;
+                TLex lex( aValue );
+                if ( !lex.Val( size ) )
+                    {
+                    aMediaObject->SetSize( size );
+                    }
+                else
+                    {
+                    ok = EFalse;
+                    }
+                }
+            break;
+            }
+
+        case EDdType:
+            {
+            ok = aMediaObject->AddTypeL( aValue );
+            break;
+            }
+
+        case EDdProgressiveDl:
+            {
+            TBool pd( EFalse );
+            if ( !aValue.CompareF( KDdTrue ) )
+                {
+                pd = ETrue;
+                }
+            else if ( aValue.CompareF( KDdFalse ) )
+                {
+                // Expected 'true' or 'false'
+                Error( KErrCodInvalidDescriptor );
+                break;
+                }
+            aMediaObject->SetProgressiveDownload( pd );
+            break;
+            }
+
+        case EDdSuppressUserConfirmation:
+            {
+            TInt confirm = CCodData::ENever; 
+            if ( !aValue.CompareF(KDdNever) )
+                {
+                confirm = CCodData::ENever; 
+                }
+            else if ( aValue.CompareF(KDdUserConfirmStepOnly) )
+                {
+                confirm = CCodData::EUserConfirmStepOnly; 
+                }
+            else if ( aValue.CompareF(KDdAlways) )
+                {
+                confirm = CCodData::EAlways;      
+                }
+            else 
+                {
+                Error( KErrCodInvalidDescriptor );
+                }
+            iData->SetSuppressConfirm( confirm );
+            break;
+            }
+        case EDdUpdatedDDURI:
+            {
+            if(!iData->UpdatedDDUriL().Length())
+                {
+                iData->SetUpdatedDDURI( aValue );
+                }
+            
+            break;
+            }
+        default:
+            {
+            // Unexpected value.
+            CodPanic( ECodInternal );
+            }
+        }
+    if ( !ok )
+        {
+        Error( KErrCodInvalidDescriptor );
+        }
+    }
+
+
+// ---------------------------------------------------------
+// TDdParser::SetMetaAttrL()
+// ---------------------------------------------------------
+//
+void TDdParser::SetMetaAttrL( TDdAttr aAttr, const TDesC& aValue )
+    {
+    TInt ok( ETrue );
+    switch( aAttr )
+        {
+        case EDdName:
+            {
+            if ( !iData->Name().Length() )
+                {
+                ok = iData->SetNameL( aValue );
+                }
+            break;
+            }
+
+        case EDdDescription:
+            {
+            if ( !iData->Description().Length() )
+                {
+                ok = iData->SetDescriptionL( aValue );
+                }
+            break;
+            }
+
+        case EDdInstallNotify:
+            {
+            if ( !iData->InstallNotify().Length() )
+                {
+                ok = iData->SetInstallNotifyL( aValue );
+                }
+            break;
+            }
+
+        case EDdInfoUrl:
+            {
+            if ( !iData->InfoUrl().Length() )
+                {
+                ok = iData->SetInfoUrlL( aValue );
+                }
+            break;
+            }
+
+        case EDdIcon:
+            {
+            if ( !iData->Icon().Length() )
+                {
+                ok = iData->SetIconL( aValue );
+                }
+            break;
+            }
+
+        case EDdOrder:
+            {
+            TBool isPostOrder( EFalse );
+            if ( !aValue.CompareF( KDdPost ) )
+                {
+                isPostOrder = ETrue;
+                }
+            else if ( aValue.CompareF( KDdAny ) )
+                {
+                // Expected 'post' or 'any'
+                Error( KErrCodInvalidDescriptor );
+                break;
+				}
+            iData->SetOrderIsPost( isPostOrder );
+            break;
+            }
+
+        case EDdText:
+            {
+
+            break;
+            }
+        default:
+            {
+            // Unexpected value.
+            CodPanic( ECodInternal );
+            }
+        }
+    if ( !ok )
+        {
+        Error( KErrCodInvalidDescriptor );
+        }
+    }
+
+
+// ---------------------------------------------------------
+// TDdParser::SetMetaAttrL()
+// ---------------------------------------------------------
+//
+void TDdParser::SetMetaAttrL( TDdAttr aAttr, const TDesC& aValue, CMediaObjectData *& aMediaObject )
+    {
+    TInt ok( ETrue );
+    switch( aAttr )
+        {
+        case EDdName:
+            {
+            if ( !aMediaObject->Name().Length() )
+                {
+                ok = aMediaObject->SetNameL( aValue );
+                }
+            break;
+            }
+
+        case EDdDescription:
+            {
+            if ( !aMediaObject->Description().Length() )
+                {
+                ok = aMediaObject->SetDescriptionL( aValue );
+                }
+            break;
+            }
+
+        case EDdInstallNotify:
+            {
+            if ( !aMediaObject->InstallNotify().Length() )
+                {
+                ok = aMediaObject->SetInstallNotifyL( aValue );
+                }
+            break;
+            }
+
+        case EDdInfoUrl:
+            {
+            if ( !aMediaObject->InfoUrl().Length() )
+                {
+                ok = aMediaObject->SetInfoUrlL( aValue );
+                }
+            break;
+            }
+
+        case EDdIcon:
+            {
+            if ( !aMediaObject->Icon().Length() )
+                {
+                ok = aMediaObject->SetIconL( aValue );
+                }
+            break;
+            }
+
+        case EDdOrder:
+            {
+            TBool isPostOrder( EFalse );
+            if ( !aValue.CompareF( KDdPost ) )
+                {
+                isPostOrder = ETrue;
+                }
+            else if ( aValue.CompareF( KDdAny ) )
+                {
+                // Expected 'post' or 'any'
+                Error( KErrCodInvalidDescriptor );
+                break;
+				}
+            aMediaObject->SetOrderIsPost( isPostOrder );
+            break;
+            }
+
+        case EDdText:
+            {
+//TODO for OMA2
+/*
+            if ( !iData->Text().Length() )
+                {
+                ok = iData->SetTextL( aValue );
+                }
+*/
+            break;
+            }
+
+        default:
+            {
+            // Unexpected value.
+            CodPanic( ECodInternal );
+            }
+        }
+    if ( !ok )
+        {
+        Error( KErrCodInvalidDescriptor );
+        }
+    }
+    
+// ---------------------------------------------------------
+// TDdParser::ParseNameFromUrlL()
+// ---------------------------------------------------------    
+void TDdParser::ParseNameFromUrlL( CMediaObjectData *& aMediaObject )
+    {
+    TBuf16<COD_URL_MAX_LEN> buf16;
+    CnvUtfConverter::ConvertToUnicodeFromUtf8(buf16,aMediaObject->Url());
+    TInt lastSlashPos = buf16.LocateReverse('/');
+    aMediaObject->SetNameL(buf16.MidTPtr( lastSlashPos + 1));
+    }
+