upnpsharing/upnpgstwrapper/src/upnprenderercfgparser.cpp
branchIOP_Improvements
changeset 40 08b5eae9f9ff
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/upnpsharing/upnpgstwrapper/src/upnprenderercfgparser.cpp	Wed Nov 03 11:45:09 2010 +0200
@@ -0,0 +1,611 @@
+/*
+* Copyright (c) 2010 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:  Implementation of UPnP GStreamer wrapper
+*
+*/
+
+// INCLUDES
+#include <xml/parser.h>
+#include <xml/parserfeature.h>
+#include <xml/matchdata.h>
+#include <xml/xmlparsererrors.h>
+#include <f32file.h>
+#include <s32file.h>
+#include <upnpaction.h>
+#include <upnpstring.h>
+
+#include "upnprenderercfg.h"
+#include "upnprenderercfgparser.h"
+
+_LIT( KComponentLogfile, "upnprenderercfgparser.txt");
+#include "upnplog.h"
+
+#define __FUNC_LOG __LOG8_1( "%s", __PRETTY_FUNCTION__ );
+
+//tags
+_LIT8( KTranscoding,             "transcoding" );
+_LIT8( KPipeline,                "pipeline" );
+_LIT8( KProtocolInfo,            "protocolInfo" );
+_LIT8( KSizeMultiplier,          "sizeMultiplier" );
+_LIT8( KRenderer,                "renderer" );
+_LIT8( KConfig,                  "config" );
+
+//attributes
+_LIT8( KExactMatch,              "exactMatch" );
+_LIT8( KModelName,               "modelName" );
+_LIT8( KSrcMimeType,             "srcMimeType" );
+
+_LIT8( KFalse,                    "0" );
+
+_LIT8( KXmlMimeType,             "text/xml" );
+_LIT8( KLIB2XML,                 "libxml2" );
+
+const TUint8 KCharSpace = 32; // Space
+const TUint8 KCharDel = 127;  // DEL
+
+using namespace Xml;
+
+// --------------------------------------------------------------------------
+// CUpnpRendererCfgParser::NewL()
+// (See comments in header file)
+// --------------------------------------------------------------------------
+//
+EXPORT_C CUpnpRendererCfgParser* CUpnpRendererCfgParser::NewL()
+    {
+    __FUNC_LOG;
+    
+    CUpnpRendererCfgParser* self = CUpnpRendererCfgParser::NewLC();
+    CleanupStack::Pop( self );    
+    return self;
+    }    
+
+// --------------------------------------------------------------------------
+// CUpnpRendererCfgParser::NewLC()
+// (See comments in header file)
+// --------------------------------------------------------------------------
+//
+EXPORT_C CUpnpRendererCfgParser* CUpnpRendererCfgParser::NewLC()
+    {
+    __FUNC_LOG;
+    
+    CUpnpRendererCfgParser* self = new( ELeave ) CUpnpRendererCfgParser();
+    CleanupStack::PushL( self );
+    self->ConstructL();
+    return self;    
+    }
+
+// --------------------------------------------------------------------------
+// CUpnpRendererCfgParser::~CUpnpRendererCfgParser()
+// (See comments in header file)
+// --------------------------------------------------------------------------
+//
+EXPORT_C CUpnpRendererCfgParser::~CUpnpRendererCfgParser()
+    {   
+    __FUNC_LOG; 
+    
+    delete iParser;
+    delete iMatchData;
+    
+    iFs.Close();
+    }
+    
+// --------------------------------------------------------------------------
+// CUpnpRendererCfgParser::CUpnpRendererCfgParser()
+// (See comments in header file)
+// --------------------------------------------------------------------------
+//
+CUpnpRendererCfgParser::CUpnpRendererCfgParser()
+    : iSizeMultiplier( KErrNotFound )
+    {
+    __FUNC_LOG;
+    // No implementation needed    
+    }
+
+// --------------------------------------------------------------------------
+// CUpnpRendererCfgParser::ConstructL()
+// (See comments in header file)
+// --------------------------------------------------------------------------
+//    
+void CUpnpRendererCfgParser::ConstructL()
+    {
+    __FUNC_LOG;
+    
+    iMatchData = CMatchData::NewL();
+    iMatchData->SetMimeTypeL( KXmlMimeType ); 
+    iMatchData->SetVariantL( KLIB2XML ); 
+    iParser = CParser::NewL( *iMatchData, *this );    
+    iParser->EnableFeature( ESendFullContentInOneChunk );
+    
+    User::LeaveIfError( iFs.Connect() );
+    }
+
+// --------------------------------------------------------------------------
+// CUpnpRendererCfgParser::ParseRendererCfgL()
+// (See comments in header file)
+// --------------------------------------------------------------------------
+//
+EXPORT_C void CUpnpRendererCfgParser::ParseRendererCfgL( 
+        CUpnpRendererCfg& aRendereConfig )
+    {     
+    __FUNC_LOG;             
+    
+    if( aRendereConfig.iPipeline || 
+        aRendereConfig.iProtocolInfo || 
+        aRendereConfig.iSizeMultiplier != KErrNotFound )
+        {
+        //these values should be still untouched
+        User::Leave( KErrArgument );
+        }
+    
+    iModelName = aRendereConfig.iModelName;
+    iSrcMimeType = aRendereConfig.iSrcMimeType;
+    
+    //syncronous call -> returns when the file is fully parsed
+    XMLParseL( *aRendereConfig.iConfigFile );
+
+    if( !iPipeline || !iProtocolInfo || iSizeMultiplier == KErrNotFound )
+        {
+        __LOG8_1( "Couldn't find all the config elements for %S", 
+                iModelName );
+        
+        //delete allocated bufs and reset vars
+        delete iPipeline; iPipeline = NULL;        
+        delete iProtocolInfo; iProtocolInfo = NULL;                
+        
+        //make sure that everything is in init state
+        Reset();
+        
+        User::Leave( KErrNotFound );
+        }
+            
+    aRendereConfig.iPipeline = iPipeline; //ownership transfer 
+    aRendereConfig.iProtocolInfo = iProtocolInfo; //ownership transfer    
+    aRendereConfig.iSizeMultiplier = iSizeMultiplier;    
+    
+    //make sure that everything is in init state
+    Reset();
+    }
+
+// --------------------------------------------------------------------------
+// CUpnpRendererCfgParser::XMLParseL()
+// (See comments in header file)
+// --------------------------------------------------------------------------
+//
+void CUpnpRendererCfgParser::XMLParseL( const TDesC& aFile )
+    {
+    __FUNC_LOG;
+   
+    RFile file;
+    User::LeaveIfError( file.Open( iFs, aFile , EFileRead ) );
+    CleanupClosePushL( file );
+    
+    TInt size;
+    User::LeaveIfError( file.Size( size ) );
+    
+    HBufC8* buf = HBufC8::NewLC( size );
+    TPtr8 ptr = buf->Des();
+    User::LeaveIfError( file.Read( ptr ) );
+    
+    Xml::ParseL( *iParser, *buf );
+    
+    CleanupStack::PopAndDestroy( buf );
+    CleanupStack::PopAndDestroy( &file );    
+    }
+
+// --------------------------------------------------------------------------
+// CUpnpRendererCfgParser::Reset()
+// (See comments in header file)
+// --------------------------------------------------------------------------
+//
+void CUpnpRendererCfgParser::Reset()
+    {
+    __FUNC_LOG;
+        
+    iCurrentElement = EUnknown;
+    iCorrectModel = EFalse;
+    iCorrectTranscoding = EFalse;
+    iModelName = NULL;
+    iSrcMimeType = NULL;
+    iPipeline = NULL;
+    iProtocolInfo = NULL;
+    iSizeMultiplier = KErrNotFound;
+    }
+    
+// --------------------------------------------------------------------------
+// CUpnpRendererCfgParser::Element()
+// (See comments in header file)
+// --------------------------------------------------------------------------
+//
+CUpnpRendererCfgParser::TCfgElements CUpnpRendererCfgParser::Element(  
+        const RTagInfo& aElement )
+    {
+    __FUNC_LOG;
+    
+    TCfgElements element = EUnknown;
+    
+    const TDesC8& desName = aElement.LocalName().DesC();   
+    
+    if( desName.CompareF( KTranscoding ) == 0 )
+        {
+        element = ETranscoding;
+        }
+    else if( desName.CompareF( KPipeline ) == 0 )
+        {
+        element = EPipeline;
+        }
+    else if( desName.CompareF( KProtocolInfo ) == 0 )
+        {
+        element = EProtocolInfo;
+        }
+    else if( desName.CompareF( KSizeMultiplier ) == 0 )
+        {
+        element = ESizeMultiplier;
+        }
+    else if( desName.CompareF( KRenderer ) == 0 )
+        {
+        element = ERenderer;
+        }
+    else if( desName.CompareF( KConfig ) == 0 )
+        {
+        element = EConfig;
+        }
+    else
+       {
+       __LOG8_1( "Error: Unknown element %S", &desName );
+       __ASSERT( EFalse, __FILE__, __LINE__ );
+       }
+       
+    return element;
+    }
+    
+// --------------------------------------------------------------------------
+// CUpnpRendererCfgParser::ContainsAttribute()
+// (See comments in header file)
+// --------------------------------------------------------------------------
+//
+TBool CUpnpRendererCfgParser::ContainsAttribute( 
+        const RAttributeArray& aAttributes, const TDesC8& aAttributeName, 
+        const TDesC8& aAttributeValue, TBool aExactValueMatch )
+    {
+    __FUNC_LOG;
+      
+    TInt attributeCount = aAttributes.Count();
+    for( TInt i = 0; i < attributeCount; i++ )
+        {
+        Xml::RAttribute attr = aAttributes[i];                      
+
+        if( attr.Attribute().LocalName().DesC() == aAttributeName )
+            {
+            if( aExactValueMatch )
+                {
+                if( aAttributeValue.CompareF( attr.Value().DesC() ) == 0 )
+                    {
+                    //requested exact value match found
+                    return ETrue;
+                    }
+                }
+            else if( aAttributeValue.FindF( attr.Value().DesC() ) >= 0 )
+                {
+                //requested non-exact value match (sub-string) found
+                return ETrue;
+                }
+            }
+        }
+        
+    return EFalse;
+    }
+
+// --------------------------------------------------------------------------
+// CUpnpRendererCfgParser::OnStartDocumentL()
+// (See comments in header file)
+// --------------------------------------------------------------------------
+//
+void CUpnpRendererCfgParser::OnStartDocumentL( 
+        const RDocumentParameters& /*aDocParam*/,
+        TInt /*aErrorCode*/ )
+    {    
+    __FUNC_LOG;
+    
+    // No implementation needed
+    }    
+
+// --------------------------------------------------------------------------
+// CUpnpRendererCfgParser::OnEndDocumentL()
+// (See comments in header file)
+// --------------------------------------------------------------------------
+//
+void CUpnpRendererCfgParser::OnEndDocumentL( TInt /*aErrorCode*/ )
+    {
+    __FUNC_LOG;
+    
+    // No implementation needed
+    }   
+
+// --------------------------------------------------------------------------
+// CUpnpRendererCfgParser::OnStartElementL()
+// (See comments in header file)
+// --------------------------------------------------------------------------
+//
+void CUpnpRendererCfgParser::OnStartElementL( const RTagInfo& aElement,
+        const RAttributeArray& aAttributes, TInt aErrorCode )
+    {    
+    __FUNC_LOG;
+    __ASSERT( !aErrorCode, __FILE__, __LINE__ );
+        
+    iCurrentElement = Element( aElement );
+    
+    switch( iCurrentElement )
+        {
+        case EConfig:         //fall through
+        case EPipeline:       //fall through
+        case EProtocolInfo:   //fall through
+        case ESizeMultiplier:
+            {
+            break;
+            }
+        case ERenderer:
+            {      
+            TBool exactMatch = ETrue;
+            if( ContainsAttribute( aAttributes, KExactMatch, KFalse, 
+                    ETrue ) )
+                {
+                exactMatch = EFalse;
+                }
+                    
+            if( ContainsAttribute( aAttributes, KModelName, *iModelName, 
+                    exactMatch ) )
+                {
+                iCorrectModel = ETrue;
+                }
+            else
+                {
+                iCorrectModel = EFalse;
+                } 
+            break;
+            }
+        case ETranscoding:
+            {
+            if( iCorrectModel &&
+                ContainsAttribute( aAttributes, KSrcMimeType, *iSrcMimeType,
+                    ETrue ) )
+                {
+                // correct transcoding found 
+                // -> assert if something is already set
+                __ASSERT( !iPipeline, __FILE__, __LINE__ );        
+                __ASSERT( !iProtocolInfo, __FILE__, __LINE__ );     
+                __ASSERT( iSizeMultiplier == KErrNotFound, __FILE__, 
+                        __LINE__ );     
+                                            
+                iCorrectTranscoding = ETrue;
+                }
+            break;
+            }
+        default:
+            {
+            __ASSERT( EFalse, __FILE__, __LINE__ );
+            }
+        }  
+    }
+
+// --------------------------------------------------------------------------
+// CUpnpRendererCfgParser::OnEndElementL()
+// (See comments in header file)
+// --------------------------------------------------------------------------
+//
+void CUpnpRendererCfgParser::OnEndElementL( const RTagInfo& aElement, 
+        TInt /*aErrorCode*/ )
+    {
+    __FUNC_LOG;
+    
+    if( iCurrentElement == EUnknown )
+        {
+        //at least second OnEndElementL callback in a row -> fetch enum
+        iCurrentElement = Element( aElement );
+        }
+    
+    switch( iCurrentElement )
+        {
+        case EPipeline:     //fall through
+        case EProtocolInfo: //fall through
+        case ESizeMultiplier:      
+            {
+            break;
+            }
+        case EUnknown:      //fall through
+        case EConfig:       //fall through
+        case ERenderer:
+            {
+            iCorrectModel = EFalse;
+            //fall through
+            }
+        case ETranscoding:
+            {
+            iCorrectTranscoding = EFalse;
+            break;
+            }
+        default:
+            {
+            __ASSERT( EFalse, __FILE__, __LINE__ );
+            }            
+        }    
+        
+    //exiting from element -> reset current element
+    iCurrentElement = EUnknown;
+    }
+
+// --------------------------------------------------------------------------
+// CUpnpRendererCfgParser::OnContentL()
+// (See comments in header file)
+// --------------------------------------------------------------------------
+//
+void CUpnpRendererCfgParser::OnContentL( const TDesC8& aBytes, 
+        TInt aErrorCode )
+    {
+    __FUNC_LOG;
+    __ASSERT( !aErrorCode, __FILE__, __LINE__ );
+    
+    TUint8 firstChar = aBytes[0];    
+    if( firstChar <= KCharSpace || firstChar == KCharDel )
+        {
+        //1st char of the content is a special char -> skip
+        return;
+        }
+    
+    switch( iCurrentElement )
+        {
+        case EConfig:   //fall through
+        case ERenderer: //fall through
+        case ETranscoding:
+            break;
+        case EPipeline:
+            {
+            if( iCorrectTranscoding )
+                {
+                //shouldn't contain any parsed value yet
+                __ASSERT( !iPipeline, __FILE__, __LINE__ );
+                       
+                iPipeline = HBufC8::NewL( aBytes.Length() );
+                iPipeline->Des().Copy( aBytes ); 
+                }
+            break;
+            }
+        case EProtocolInfo:
+            {
+            if( iCorrectTranscoding )
+                {
+                //shouldn't contain any parsed value yet
+                __ASSERT( !iProtocolInfo, __FILE__, __LINE__ );
+                
+                iProtocolInfo = HBufC8::NewL( aBytes.Length() );
+                iProtocolInfo->Des().Copy( aBytes ); 
+                }
+            break;
+            }
+        case ESizeMultiplier:
+            {
+            if( iCorrectTranscoding )
+                {
+                //shouldn't contain any parsed value yet
+                __ASSERT( iSizeMultiplier == KErrNotFound, __FILE__, 
+                        __LINE__ );
+                
+                TLex8 lex;
+                lex.Assign( aBytes );                
+                TInt err = lex.Val( iSizeMultiplier );
+                
+                __ASSERT( !err, __FILE__, __LINE__ );
+                }
+            break;
+            }
+        default:
+            {
+            __ASSERT( EFalse, __FILE__, __LINE__ );
+            }            
+        }
+    }
+
+// --------------------------------------------------------------------------
+// CUpnpRendererCfgParser::OnStartPrefixMappingL()
+// (See comments in header file)
+// --------------------------------------------------------------------------
+//
+void CUpnpRendererCfgParser::OnStartPrefixMappingL( 
+        const RString& /*aPrefix*/, const RString& /*aUri*/, 
+        TInt /*aErrorCode*/ )
+    {
+    __FUNC_LOG;
+    
+    // No implementation needed
+    }
+// --------------------------------------------------------------------------
+// CUpnpRendererCfgParser::OnEndPrefixMappingL()
+// (See comments in header file)
+// --------------------------------------------------------------------------
+//
+void CUpnpRendererCfgParser::OnEndPrefixMappingL( const RString& /*aPrefix*/,
+        TInt /*aErrorCode*/ )
+    {
+    __FUNC_LOG;
+    
+    // No implementation needed
+    }
+
+// --------------------------------------------------------------------------
+// CUpnpRendererCfgParser::OnIgnorableWhiteSpaceL()
+// (See comments in header file)
+// --------------------------------------------------------------------------
+//
+void CUpnpRendererCfgParser::OnIgnorableWhiteSpaceL( const TDesC8& /*aBytes*/, 
+        TInt /*aErrorCode*/ )
+    {
+    __FUNC_LOG;
+    
+    // No implementation needed
+    }
+
+// --------------------------------------------------------------------------
+// CUpnpRendererCfgParser::OnSkippedEntityL()
+// (See comments in header file)
+// --------------------------------------------------------------------------
+//
+void CUpnpRendererCfgParser::OnSkippedEntityL( const RString& /*aName*/, 
+        TInt /*aErrorCode*/ )
+    {
+    __FUNC_LOG;
+    
+    // No implementation needed
+    }
+
+// --------------------------------------------------------------------------
+// CUpnpRendererCfgParser::OnProcessingInstructionL()
+// (See comments in header file)
+// --------------------------------------------------------------------------
+//
+void CUpnpRendererCfgParser::OnProcessingInstructionL( 
+        const TDesC8& /*aTarget*/, 
+        const TDesC8& /*aData*/,
+        TInt /*aErrorCode*/ )
+    {
+    __FUNC_LOG;
+    
+    // No implementation needed
+    } 
+
+// --------------------------------------------------------------------------
+// CUpnpRendererCfgParser::OnError()
+// (See comments in header file)
+// --------------------------------------------------------------------------
+//
+void CUpnpRendererCfgParser::OnError( TInt /*aErrorCode*/ )
+    {
+    __FUNC_LOG;
+    
+    // No implementation needed
+    }  
+
+// --------------------------------------------------------------------------
+// CUpnpRendererCfgParser::GetExtendedInterface()
+// (See comments in header file)
+// --------------------------------------------------------------------------
+//
+TAny* CUpnpRendererCfgParser::GetExtendedInterface( const TInt32 /*aUid*/ )
+    {
+    __FUNC_LOG;
+    
+    // No implementation needed
+    return NULL;
+    }
+
+
+// end of file