diff -r 6369bfd1b60d -r 08b5eae9f9ff upnpsharing/upnpgstwrapper/src/upnprenderercfgparser.cpp --- /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 +#include +#include +#include +#include +#include +#include +#include + +#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