--- /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