diff -r 000000000000 -r ba25891c3a9e iaupdate/IAD/engine/controller/src/iaupdatexmlsubparser.cpp --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/iaupdate/IAD/engine/controller/src/iaupdatexmlsubparser.cpp Thu Dec 17 08:51:10 2009 +0200 @@ -0,0 +1,316 @@ +/* +* Copyright (c) 2009 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: ?Description +* +*/ + + + +#include +#include +#include + +#include "iaupdatexmlsubparser.h" + + +EXPORT_C CIAUpdateXmlSubParser::CIAUpdateXmlSubParser() +: CBase(), + iAcceptData( ETrue ) + { + + } + + +EXPORT_C void CIAUpdateXmlSubParser::ConstructL( const TDesC8& aElementLocalName ) + { + iElementLocalName = aElementLocalName.AllocL(); + } + + +EXPORT_C CIAUpdateXmlSubParser::~CIAUpdateXmlSubParser() + { + // Notice, this array also owns the iCurrentSubParser. + // So, do not delete it twice. ResetAndDestroy here is enough. + iSubParsers.ResetAndDestroy(); + + delete iElementLocalName; + } + + +EXPORT_C void CIAUpdateXmlSubParser::OnStartDocumentL( + const Xml::RDocumentParameters& aDocParam, + TInt aErrorCode ) + { + iAcceptData = ETrue; + iUnknownElementCounter = 0; + iIsElementStarted = EFalse; + iIsElementEnded = EFalse; + for ( TInt i = 0; i < iSubParsers.Count(); ++i ) + { + iSubParsers[ i ]->OnStartDocumentL( aDocParam, aErrorCode ); + } + } + +EXPORT_C void CIAUpdateXmlSubParser::OnEndDocumentL( TInt /*aErrorCode*/ ) + { + // Nothing to do here. + // Child class may add more functionality in its own implementation + // if necessary. + } + +EXPORT_C void CIAUpdateXmlSubParser::OnStartElementL( const Xml::RTagInfo& aElement, + const Xml::RAttributeArray& aAttributes, + TInt aErrorCode ) + { + if ( CurrentSubParser() ) + { + // Because current sub parser has been set, it is its responsibility to handle + // the element. + CurrentSubParser()->OnStartElementL( aElement, aAttributes, aErrorCode ); + } + else if ( !IsElementStarted() + && ElementTagInfoEquals( aElement ) ) + { + // The starting element for this sub parser element was called. + // Reset the flags just in case. + // And, set the started flag to ETrue; + iIsElementStarted = ETrue; + iAcceptData = ETrue; + iIsElementEnded = EFalse; + iUnknownElementCounter = 0; + } + else if ( IsElementStarted() + && AcceptData() ) + { + // First time case has already been handled. + // Because flags suggests that the handling of element is + // job of the sub parser of this sub parser, try to check + // if we can delegate it to some sub parsers. + // Also, set the AcceptData flag accordingly. + // If sub parser is found then, then the job is its responsibility and + // if sub parser is not found, then some unknown element is at hand. + // So, in both cases set the flag to false. + iAcceptData = EFalse; + + // Sub parser has not been set. So, check if we can find a subparser for the job. + for ( TInt i = 0; i < iSubParsers.Count(); ++i ) + { + if ( iSubParsers[ i ]->ElementTagInfoEquals( aElement ) ) + { + // A correct sub parser was found because element tag matched + // to the given element. + iCurrentSubParser = iSubParsers[ i ]; + + // Now, let the sub parser handle the element. + CurrentSubParser()->OnStartElementL( aElement, aAttributes, aErrorCode ); + + // No need to check sub parsers any more. + // Notice, that in the scheme there will be only one element of a kind but + // in action some elements may contain multiple instances of the same element. + // But, this will be handled inside container element separately. + break; + } + } + + if ( !iCurrentSubParser ) + { + // Element was unknown. + ++iUnknownElementCounter; + } + } + else + { + // If we got some unknown element. + // Set the AcceptData flag to EFalse. + iAcceptData = EFalse; + ++iUnknownElementCounter; + } + } + +EXPORT_C void CIAUpdateXmlSubParser::OnEndElementL( const Xml::RTagInfo& aElement, + TInt aErrorCode ) + { + if ( CurrentSubParser() ) + { + // Because current sub parser has been set + // and it has not finished its job yet, + // it is its responsibility to handle the element. + CurrentSubParser()->OnEndElementL( aElement, aErrorCode ); + + if ( CurrentSubParser()->IsElementEnded() ) + { + // Because current sub parser has finished its job. + // This parser should not have any sub parser set any more. + iCurrentSubParser = NULL; + + // Because the sub parser has finished it job, + // this parser can now accept new sub elements if necessary. + // Note, that this does not mean that this element would + // finish next. + iAcceptData = ETrue; + } + } + else if( UnknownElementCounter() == 0 ) + { + // This sub parser has finished its job. + // Set accept flag to its default now because + // the element has been handled. + iAcceptData = ETrue; + iIsElementStarted = EFalse; + iIsElementEnded = ETrue; + } + else if( UnknownElementCounter() == 1 ) + { + --iUnknownElementCounter; + // We have handled all the unknowns now. + iAcceptData = ETrue; + } + else + { + // We got the unknown element end now for this sub parser. + --iUnknownElementCounter; + } + } + +EXPORT_C void CIAUpdateXmlSubParser::OnContentL( const TDesC8& aBytes, + TInt aErrorCode ) + { + if ( CurrentSubParser() ) + { + // Because current sub parser has been set, it is its responsibility to handle + // the element. + CurrentSubParser()->OnContentL( aBytes, aErrorCode ); + } + } + +EXPORT_C void CIAUpdateXmlSubParser::OnStartPrefixMappingL( const RString& /*aPrefix*/, + const RString& /*aUri*/, + TInt /*aErrorCode*/ ) + { + // Nothing to do here. + // Child class may add more functionality in its own implementation + // if necessary. + } + +EXPORT_C void CIAUpdateXmlSubParser::OnEndPrefixMappingL( const RString& /*aPrefix*/, + TInt /*aErrorCode*/ ) + { + // Nothing to do here. + // Child class may add more functionality in its own implementation + // if necessary. + } + +EXPORT_C void CIAUpdateXmlSubParser::OnIgnorableWhiteSpaceL( const TDesC8& /*aBytes*/, + TInt /*aErrorCode*/ ) + { + // Nothing to do here. + // Child class may add more functionality in its own implementation + // if necessary. + } + +EXPORT_C void CIAUpdateXmlSubParser::OnSkippedEntityL( const RString& /*aName*/, + TInt /*aErrorCode*/ ) + { + // Nothing to do here. + // Child class may add more functionality in its own implementation + // if necessary. + } + +EXPORT_C void CIAUpdateXmlSubParser::OnProcessingInstructionL( const TDesC8& /*aTarget*/, + const TDesC8& /*aData*/, + TInt /*aErrorCode*/ ) + { + // Nothing to do here. + // Child class may add more functionality in its own implementation + // if necessary. + } + +EXPORT_C void CIAUpdateXmlSubParser::OnError( TInt /*aErrorCode*/ ) + { + // Nothing to do here. + // Child class may add more functionality in its own implementation + // if necessary. + } + +EXPORT_C TAny* CIAUpdateXmlSubParser::GetExtendedInterface( const TInt32 /*aUid*/ ) + { + // Nothing to do here. + // Child class may add more functionality in its own implementation + // if necessary. + return NULL; + } + + +EXPORT_C const TDesC8& CIAUpdateXmlSubParser::LocalName() const + { + return *iElementLocalName; + } + + +EXPORT_C CIAUpdateXmlSubParser* CIAUpdateXmlSubParser::CurrentSubParser() const + { + return iCurrentSubParser; + } + + +EXPORT_C RPointerArray< CIAUpdateXmlSubParser >& CIAUpdateXmlSubParser::SubParsers() + { + return iSubParsers; + } + + +EXPORT_C TBool CIAUpdateXmlSubParser::ElementTagInfoEquals( const Xml::RTagInfo& aElement ) const + { + // Get the element local name from the given parameter. + const TDesC8& element( aElement.LocalName().DesC() ); + + // Now, chek if the given element has the same name with the element that this + // parser is created for. Notice, that the element names are specified as case sensitive. + // But, element values are not specified as case sensitive. + if ( element == LocalName() ) + { + // The given element tag matched with the local name of this class object. + return ETrue; + } + else + { + // The local names did not match. + return EFalse; + } + } + + +EXPORT_C TBool CIAUpdateXmlSubParser::AcceptData() const + { + return iAcceptData; + } + + +EXPORT_C TBool CIAUpdateXmlSubParser::IsElementStarted() const + { + return iIsElementStarted; + } + + +EXPORT_C TBool CIAUpdateXmlSubParser::IsElementEnded() const + { + return iIsElementEnded; + } + + +EXPORT_C TInt CIAUpdateXmlSubParser::UnknownElementCounter() const + { + return iUnknownElementCounter; + } +