--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/srsf/vcommandmanager/src/vcxmlparser.cpp Thu Dec 17 08:46:30 2009 +0200
@@ -0,0 +1,1181 @@
+/*
+* Copyright (c) 2005-2007 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: Parser for Voice Commands XML files
+*
+*/
+
+
+// INCLUDE FILES
+#include <e32math.h>
+#include <featmgr.h>
+#include <parser.h>
+#include <utf.h>
+#include "vcxmlparser.h"
+#include "vcresource.h"
+#include "rubydebug.h"
+
+// CONSTANTS
+// XML Tags
+_LIT8( KXmlDocumentTag, "nssvcommands" );
+_LIT8( KXmlFolderTag, "vcommandfolder" );
+_LIT8( KXmlVCommandTag, "vcommand" );
+_LIT8( KXmlSpokenTag, "spoken" );
+_LIT8( KXmlWrittenTag, "written" );
+_LIT8( KXmlExecutesTag, "executes" );
+_LIT8( KXmlCmdlineparamsTag, "cmdlineparams" );
+_LIT8( KXmlIconTag, "icon" );
+_LIT8( KXmlTooltipTag, "tooltip" );
+
+// XML attributes
+_LIT8( KXmlVersionAttr, "version" );
+_LIT8( KXmlLocFileAttr, "localizationfile" );
+_LIT8( KXmlLocAttr, "locindex" );
+_LIT8( KXmlFolderTitleLocAttr, "titlelocindex" );
+_LIT8( KXmlFolderIconFileAttr, "iconfile" );
+_LIT8( KXmlFolderIconIndexAttr, "iconindex" );
+_LIT8( KXmlTtsAttr, "tts" );
+_LIT8( KXmlModifiableAttr, "modifiable" );
+_LIT8( KXmlUidAttr, "uid" );
+_LIT8( KXmlExeAttr, "exe" );
+
+// XML attribute values
+_LIT8( KXmlVersionValue, "1.0" );
+_LIT8( KXmlTrueValue, "true" );
+_LIT8( KXmlFalseValue, "false" );
+
+// XML file MIME type
+_LIT8( KMimeType, "text/xml" );
+
+static const TInt KNoTags = 0;
+static const TInt KLastTag = 1;
+
+// ============================ MEMBER FUNCTIONS ===============================
+
+// -----------------------------------------------------------------------------
+// CVcXmlParser::CVcXmlParser
+// C++ default constructor can NOT contain any code, that
+// might leave.
+// -----------------------------------------------------------------------------
+//
+CVcXmlParser::CVcXmlParser( RFs& aRFs, MVcXmlParserObserver& aObserver )
+ : iObserver( aObserver ), iRFs( aRFs )
+ {
+ // Nothing
+ }
+
+// -----------------------------------------------------------------------------
+// CVcXmlParser::ConstructL
+// Symbian 2nd phase constructor can leave.
+// -----------------------------------------------------------------------------
+//
+void CVcXmlParser::ConstructL()
+ {
+ RUBY_DEBUG_BLOCK( "CVcXmlParser::ConstructL" );
+
+ ResetVCommandFolder();
+
+ using namespace Xml;
+
+ iParser = CParser::NewL( KMimeType, *this );
+ }
+
+// -----------------------------------------------------------------------------
+// CVcXmlParser::NewL
+// Two-phased constructor.
+// -----------------------------------------------------------------------------
+//
+CVcXmlParser* CVcXmlParser::NewL( RFs& aRFs, MVcXmlParserObserver& aObserver )
+ {
+ CVcXmlParser* self = new( ELeave ) CVcXmlParser( aRFs, aObserver );
+ CleanupStack::PushL( self );
+ self->ConstructL();
+ CleanupStack::Pop( self );
+ return self;
+ }
+
+// -----------------------------------------------------------------------------
+// CVcXmlParser::~CVcXmlParser
+// Destructor.
+// -----------------------------------------------------------------------------
+//
+CVcXmlParser::~CVcXmlParser()
+ {
+ iXmlNesting.Close();
+ ResetVCommandInfo();
+ delete iResource;
+ delete iFolder;
+ delete iFolderTitle;
+ delete iFolderIconFile;
+ delete iAttributeValue;
+ delete iParser;
+ delete iParameters;
+ delete iParameters8;
+ delete iAppName;
+ }
+
+// -----------------------------------------------------------------------------
+// CVcXmlParser::ParseFileL
+// Parses a specific file.
+// -----------------------------------------------------------------------------
+//
+void CVcXmlParser::ParseFileL( const TFileName& aFileName )
+ {
+ RUBY_DEBUG_BLOCK( "CVcXmlParser::ParseFileL" );
+
+ iParser->ParseBeginL();
+
+ ParseL( *iParser, iRFs, aFileName );
+ }
+
+// -----------------------------------------------------------------------------
+// CVcXmlParser::OnStartDocumentL
+// Callback from XML parser when beginning of document has been found
+// -----------------------------------------------------------------------------
+//
+void CVcXmlParser::OnStartDocumentL( const Xml::RDocumentParameters& /*aDocParam*/,
+ TInt aErrorCode )
+ {
+ RUBY_DEBUG_BLOCKL( "CVcXmlParser::OnStartDocumentL" );
+
+ delete iResource;
+ iResource = NULL;
+
+ if ( ( iXmlNesting.Count() == KNoTags ) && ( aErrorCode == KErrNone ) )
+ {
+ iXmlNesting.Append( EXmlStarted );
+ }
+ else
+ {
+ User::Leave( KErrGeneral );
+ }
+ }
+
+// -----------------------------------------------------------------------------
+// CVcXmlParser::OnEndDocumentL
+// Callback from XML parser when end of document has been reached
+// -----------------------------------------------------------------------------
+//
+void CVcXmlParser::OnEndDocumentL( TInt aErrorCode )
+ {
+ RUBY_DEBUG_BLOCKL( "CVcXmlParser::OnEndDocumentL" );
+
+ if ( ( iXmlNesting.Count() == KLastTag ) && ( aErrorCode == KErrNone ) )
+ {
+ iXmlNesting.Reset();
+ }
+ else
+ {
+ User::Leave( KErrGeneral );
+ }
+ }
+
+// -----------------------------------------------------------------------------
+// CVcXmlParser::OnStartElementL
+// Callback from XML parser when new element has been found
+// -----------------------------------------------------------------------------
+//
+void CVcXmlParser::OnStartElementL( const Xml::RTagInfo& aElement,
+ const Xml::RAttributeArray& aAttributes,
+ TInt aErrorCode )
+ {
+ RUBY_DEBUG_BLOCKL( "CVcXmlParser::OnStartElementL" );
+ __ASSERT_ALWAYS( iXmlNesting.Count() > 0, User::Leave( KErrCorrupt ) );
+
+ User::LeaveIfError( aErrorCode );
+
+ HBufC8* name = ToLowercaseLC( aElement.LocalName().DesC() );
+
+ // Check what was the previous tag
+ switch ( iXmlNesting[ iXmlNesting.Count() - 1 ] )
+ {
+ case EXmlStarted:
+ {
+ if ( !ResolveDocumentTagL( name->Des(), aAttributes ) )
+ {
+ User::Leave( KErrNotFound );
+ }
+ break;
+ }
+
+ case EXmlDocument:
+ {
+ if ( !ResolveFolderTagL( name->Des(), aAttributes ) )
+ {
+ if ( !ResolveVCommandTagL( name->Des(), aAttributes ) )
+ {
+ RUBY_DEBUG0( "VC XML ERROR: <vcommandfolder> or <vcommand> exptected but not found" );
+ User::Leave( KErrNotFound );
+ }
+ }
+ break;
+ }
+
+ case EXmlFolder:
+ {
+ if ( !ResolveVCommandTagL( name->Des(), aAttributes ) )
+ {
+ RUBY_DEBUG0( "VC XML ERROR: <vcommand> exptected but not found" );
+ User::Leave( KErrNotFound );
+ }
+
+ // New voice command starts
+ ResetVCommandInfo();
+
+ break;
+ }
+
+ case EXmlVCommand:
+ {
+ if ( !ResolveSpokenTagL( name->Des(), aAttributes ) )
+ {
+ if ( !ResolveWrittenTagL( name->Des(), aAttributes ) )
+ {
+ if ( !ResolveExecutesTagL( name->Des(), aAttributes ) )
+ {
+ if ( !ResolveCmdlineparamsTag( name->Des(), aAttributes ) )
+ {
+ if ( !ResolveIconTagL( name->Des(), aAttributes ) )
+ {
+ if ( !ResolveTooltipTagL( name->Des(), aAttributes ) )
+ {
+ RUBY_DEBUG0( "VC XML ERROR: <spoken> <written> <executes> or <cmdlineparams> exptected but not found" );
+ User::Leave( KErrNotFound );
+ }
+ }
+ }
+ }
+ }
+ }
+ break;
+ }
+
+ default:
+ {
+
+ RUBY_DEBUG0( "VC XML ERROR: Unexpected starting tag found" );
+ User::Leave( KErrNotFound );
+
+ break;
+ }
+
+ }
+
+ CleanupStack::PopAndDestroy( name );
+
+ }
+
+// -----------------------------------------------------------------------------
+// CVcXmlParser::OnEndElementL
+// Callback from XML parser when ending tag has been found
+// -----------------------------------------------------------------------------
+//
+void CVcXmlParser::OnEndElementL( const Xml::RTagInfo& aElement,
+ TInt aErrorCode )
+ {
+ RUBY_DEBUG_BLOCKL( "CVcXmlParser::OnEndElementL" );
+ __ASSERT_ALWAYS( iXmlNesting.Count() > 0, User::Leave( KErrCorrupt ) );
+
+ User::LeaveIfError( aErrorCode );
+
+ HBufC8* name = ToLowercaseLC( aElement.LocalName().DesC() );
+
+ switch ( iXmlNesting[ iXmlNesting.Count() - 1 ] )
+ {
+ case EXmlDocument:
+ {
+ PopFromStackIfFoundL( name->Des(), KXmlDocumentTag );
+ break;
+ }
+
+ case EXmlFolder:
+ {
+ PopFromStackIfFoundL( name->Des(), KXmlFolderTag );
+ ResetVCommandFolder();
+ break;
+ }
+
+ case EXmlVCommand:
+ {
+ PopFromStackIfFoundL( name->Des(), KXmlVCommandTag );
+ CheckVoiceCommmandData();
+ break;
+ }
+
+ case EXmlSpoken:
+ {
+ PopFromStackIfFoundL( name->Des(), KXmlSpokenTag );
+ break;
+ }
+
+ case EXmlWritten:
+ {
+ PopFromStackIfFoundL( name->Des(), KXmlWrittenTag );
+ break;
+ }
+
+ case EXmlExecutes:
+ {
+ PopFromStackIfFoundL( name->Des(), KXmlExecutesTag );
+ break;
+ }
+
+ case EXmlCmdlineparams:
+ {
+ PopFromStackIfFoundL( name->Des(), KXmlCmdlineparamsTag );
+
+ // Convert content of <cmdlineparams> into unicode
+ // First trim out unnecessary white space
+ TPtr8 des8( iParameters8->Des() );
+ des8.Trim();
+
+ // Delete previous unicode buffer and create new
+ delete iParameters;
+ iParameters = NULL;
+ iParameters = CnvUtfConverter::ConvertToUnicodeFromUtf8L( des8 );
+
+ break;
+ }
+
+ case EXmlIcon:
+ {
+ PopFromStackIfFoundL( name->Des(), KXmlIconTag );
+ break;
+ }
+
+ case EXmlTooltip:
+ {
+ PopFromStackIfFoundL( name->Des(), KXmlTooltipTag );
+ break;
+ }
+
+ default:
+ {
+ RUBY_DEBUG0( "VC XML ERROR: Ending tag found when not expected" );
+ User::Leave( KErrGeneral );
+ break;
+ }
+
+ }
+ CleanupStack::PopAndDestroy( name );
+ }
+
+// -----------------------------------------------------------------------------
+// CVcXmlParser::PopFromStackIfFoundL
+// Checks that last item on stack is the expected one
+// -----------------------------------------------------------------------------
+//
+void CVcXmlParser::PopFromStackIfFoundL( const TDesC8& aTagName, const TDesC8& aExpectedTag )
+ {
+ if ( aTagName != aExpectedTag )
+ {
+ RUBY_DEBUG0( "VC XML ERROR: Unexpected ending tag found" );
+ User::Leave( KErrNotFound );
+ }
+
+ iXmlNesting.Remove( iXmlNesting.Count() - 1 );
+ }
+
+// -----------------------------------------------------------------------------
+// CVcXmlParser::OnContentL
+// Callback from XML parser when element has some content
+// -----------------------------------------------------------------------------
+//
+void CVcXmlParser::OnContentL( const TDesC8& aBytes, TInt aErrorCode )
+ {
+ RUBY_DEBUG_BLOCKL( "CVcXmlParser::OnContentL" );
+
+ User::LeaveIfError( aErrorCode );
+
+ TInt lastTag = iXmlNesting.Count() - 1;
+
+ if ( iXmlNesting[ lastTag ] == EXmlCmdlineparams )
+ {
+ if ( !iParameters8 )
+ {
+ // Create new buffer
+ iParameters8 = HBufC8::NewL( aBytes.Size() );
+ TPtr8 des( iParameters8->Des() );
+ des.Copy( aBytes );
+ }
+ else
+ {
+ // Append at the end of previous stuff
+ iParameters8 = iParameters8->ReAllocL( iParameters8->Size() + aBytes.Size() );
+ TPtr8 des( iParameters8->Des() );
+ des.Append( aBytes );
+ }
+
+ RUBY_DEBUG0( "<cmdlineparams> content resolved" );
+ }
+ }
+
+// -----------------------------------------------------------------------------
+// CVcXmlParser::OnStartPrefixMappingL
+// Callback from XML parser
+// -----------------------------------------------------------------------------
+//
+void CVcXmlParser::OnStartPrefixMappingL( const RString& /*aPrefix*/,
+ const RString& /*aUri*/,
+ TInt /*aErrorCode*/ )
+ {
+ // Nothing
+ }
+
+// -----------------------------------------------------------------------------
+// CVcXmlParser::OnEndPrefixMappingL
+// Callback from XML parser
+// -----------------------------------------------------------------------------
+//
+void CVcXmlParser::OnEndPrefixMappingL( const RString& /*aPrefix*/,
+ TInt /*aErrorCode*/ )
+ {
+ // Nothing
+ }
+
+// -----------------------------------------------------------------------------
+// CVcXmlParser::OnIgnorableWhiteSpaceL
+// Callback from XML parser
+// -----------------------------------------------------------------------------
+//
+void CVcXmlParser::OnIgnorableWhiteSpaceL( const TDesC8& /*aBytes*/,
+ TInt /*aErrorCode*/ )
+ {
+ // Nothing
+ }
+
+// -----------------------------------------------------------------------------
+// CVcXmlParser::OnSkippedEntityL
+// Callback from XML parser
+// -----------------------------------------------------------------------------
+//
+void CVcXmlParser::OnSkippedEntityL( const RString& /*aName*/,
+ TInt /*aErrorCode*/ )
+ {
+ // Nothing
+ }
+
+// -----------------------------------------------------------------------------
+// CVcXmlParser::OnProcessingInstructionL
+// Callback from XML parser
+// -----------------------------------------------------------------------------
+//
+void CVcXmlParser::OnProcessingInstructionL( const TDesC8& /*aTarget*/,
+ const TDesC8& /*aData*/,
+ TInt /*aErrorCode*/ )
+ {
+ // Nothing
+ }
+
+// -----------------------------------------------------------------------------
+// CVcXmlParser::OnError
+// Callback from XML parser when general error has occured
+// -----------------------------------------------------------------------------
+//
+#if defined(_DEBUG) && !defined(__RUBY_DEBUG_DISABLED)
+void CVcXmlParser::OnError( TInt aErrorCode )
+ {
+ RUBY_DEBUG1( "CVcXmlParser::OnError general error: [%d]", aErrorCode );
+ }
+#else
+void CVcXmlParser::OnError( TInt /*aErrorCode*/ )
+ {
+ // Nothing
+ }
+#endif // #if defined(_DEBUG) && !defined(__RUBY_DEBUG_DISABLED)
+
+// -----------------------------------------------------------------------------
+// CVcXmlParser::GetExtendedInterface
+// Callback from XML parser
+// -----------------------------------------------------------------------------
+//
+TAny* CVcXmlParser::GetExtendedInterface( const TInt32 /*aUid*/ )
+ {
+ return NULL;
+ }
+
+// -----------------------------------------------------------------------------
+// CVcXmlParser::CheckAttributeL
+// Checks the value of certain attribute
+// -----------------------------------------------------------------------------
+//
+TBool CVcXmlParser::CheckAttributeL( const Xml::RAttributeArray& aAttributes,
+ const TDesC8& aAttribute, const TDesC8& aValue )
+ {
+ RUBY_DEBUG_BLOCKL( "CVcXmlParser::CheckAttributeL" );
+
+ TBool resolved( EFalse );
+
+ // Loop through attribute list
+ for ( TInt iCounter = 0 ; iCounter < aAttributes.Count() ; iCounter++ )
+ {
+ HBufC8* name = ToLowercaseLC( aAttributes[iCounter].Attribute().LocalName().DesC() );
+
+ if ( name->Des() == aAttribute )
+ {
+ HBufC8* value = ToLowercaseLC( aAttributes[iCounter].Value().DesC() );
+
+ // If value is null descriptor, then we just check if attribute exists
+ if ( aValue == KNullDesC8 || value->Des() == aValue )
+ {
+ resolved = ETrue;
+ }
+
+ CleanupStack::PopAndDestroy( value );
+ }
+ CleanupStack::PopAndDestroy( name );
+ }
+
+ return resolved;
+ }
+
+// -----------------------------------------------------------------------------
+// CVcXmlParser::ResolveDocumentTagL
+// Resolves the content of <nssvcommands>
+// -----------------------------------------------------------------------------
+//
+TBool CVcXmlParser::ResolveDocumentTagL( const TDesC8& aName,
+ const Xml::RAttributeArray& aAttributes )
+ {
+ RUBY_DEBUG_BLOCKL( "CVcXmlParser::ResolveDocumentTagL" );
+
+ TBool resolved( EFalse );
+
+ if ( aName == KXmlDocumentTag )
+ {
+ iXmlNesting.Append( EXmlDocument );
+ resolved = CheckAttributeL( aAttributes, KXmlVersionAttr, KXmlVersionValue );
+ if ( !resolved )
+ {
+ RUBY_DEBUG0( "VC XML ERROR: Version information not found or it does not match" );
+ User::Leave( KErrGeneral );
+ }
+ else
+ {
+ CVcResource* newResource( NULL );
+ TPtrC8 locFileAttr( KXmlLocFileAttr );
+ TRAPD( error, newResource =
+ CVcResource::NewL( iRFs, Find16ValueL( locFileAttr, aAttributes ) ) );
+
+ // Delete old resource object if new was found
+ if ( newResource )
+ {
+ delete iResource;
+ iResource = newResource;
+ }
+
+ if ( error != KErrNone )
+ {
+ resolved = EFalse;
+ RUBY_DEBUG0( "VC XML ERROR: Resource file load error" );
+ User::Leave( KErrNotFound );
+ }
+ }
+ }
+ else
+ {
+ RUBY_DEBUG0( "VC XML ERROR: <nssvoicecommands> exptected but not found" );
+ User::Leave( KErrNotFound );
+ }
+
+ return resolved;
+ }
+
+// -----------------------------------------------------------------------------
+// CVcXmlParser::ResolveFolderTagL
+// Resolves the content of <vcommandfolder>
+// -----------------------------------------------------------------------------
+//
+TBool CVcXmlParser::ResolveFolderTagL( const TDesC8& aName,
+ const Xml::RAttributeArray& aAttributes )
+ {
+ RUBY_DEBUG_BLOCKL( "CVcXmlParser::ResolveFolderTagL" );
+
+ // Use specific resource file for folder strings if specified
+ CVcResource* mainResource = iResource;
+
+ CVcResource* newResource( NULL );
+ TPtrC locFile = Find16ValueL( KXmlLocFileAttr, aAttributes );
+ if ( locFile != KNullDesC )
+ {
+ newResource = CVcResource::NewL( iRFs, locFile );
+ }
+
+ if ( newResource )
+ {
+ iResource = newResource;
+ CleanupStack::PushL( mainResource );
+ }
+
+ // Find folder name
+ TBool resolved = ResolveLocalizedTagL( aName, aAttributes, KXmlFolderTag,
+ EXmlFolder );
+ if ( resolved )
+ {
+ delete iFolder;
+ iFolder = iCurrentLocalizedString;
+ iCurrentLocalizedString = NULL;
+
+ // Find folder title string
+ TBool titleFound = GetLocalizedStringL( aAttributes, KXmlFolderTitleLocAttr );
+
+ if ( titleFound )
+ {
+ delete iFolderTitle;
+ iFolderTitle = iCurrentLocalizedString;
+ iCurrentLocalizedString = NULL;
+ }
+
+ TBool iconFileFound = ResolveFolderIconFileL( aAttributes );
+ RUBY_DEBUG1( "iconFileFound [%d]", iconFileFound );
+ iFolderIconIndex = ResolveFolderIconIndexL( aAttributes );
+
+ }
+
+ // Revert back to use the old resource file
+ iResource = mainResource;
+ if ( newResource )
+ {
+ delete newResource;
+ CleanupStack::Pop( mainResource );
+ }
+
+ return resolved;
+ }
+
+// -----------------------------------------------------------------------------
+// CVcXmlParser::ResolveVCommandTagL
+// Resolves the content of <vcommand>
+// -----------------------------------------------------------------------------
+//
+TBool CVcXmlParser::ResolveVCommandTagL( const TDesC8& aName,
+ const Xml::RAttributeArray& aAttributes )
+ {
+ RUBY_DEBUG_BLOCKL( "CVcXmlParser::ResolveVCommandTagL" );
+
+ TBool resolved( EFalse );
+ if ( aName == KXmlVCommandTag )
+ {
+ resolved = ETrue;
+ iXmlNesting.Append( EXmlVCommand );
+ }
+
+ if ( resolved )
+ {
+ // TTS on/off
+ resolved = CheckAttributeL( aAttributes, KXmlTtsAttr, KXmlTrueValue );
+ if ( resolved )
+ {
+ // By default, tts is on
+ iStartImmediately = ETrue;
+ }
+
+ // Modifiable on/off
+ resolved = CheckAttributeL( aAttributes, KXmlModifiableAttr, KXmlFalseValue );
+ if ( resolved )
+ {
+ iUserCanModify = EFalse;
+ }
+
+ resolved = ETrue;
+ }
+
+ return resolved;
+ }
+
+
+// -----------------------------------------------------------------------------
+// CVcXmlParser::ResolveSpokenTagL
+// Resolves the content of <spoken>
+// -----------------------------------------------------------------------------
+//
+TBool CVcXmlParser::ResolveSpokenTagL( const TDesC8& aName,
+ const Xml::RAttributeArray& aAttributes )
+ {
+ RUBY_DEBUG_BLOCKL( "CVcXmlParser::ResolveSpokenTagL" );
+
+ TBool resolved = ResolveLocalizedTagL( aName, aAttributes, KXmlSpokenTag,
+ EXmlSpoken );
+
+ if ( resolved )
+ {
+ delete iSpokenText;
+ iSpokenText = iCurrentLocalizedString;
+ iCurrentLocalizedString = NULL;
+ }
+ return resolved;
+ }
+
+// -----------------------------------------------------------------------------
+// CVcXmlParser::ResolveWrittenTagL
+// Resolves the content of <written>
+// -----------------------------------------------------------------------------
+//
+TBool CVcXmlParser::ResolveWrittenTagL( const TDesC8& aName,
+ const Xml::RAttributeArray& aAttributes )
+ {
+ RUBY_DEBUG_BLOCKL( "CVcXmlParser::ResolveWrittenTagL" );
+
+ TBool resolved = ResolveLocalizedTagL( aName, aAttributes, KXmlWrittenTag,
+ EXmlWritten );
+ if ( resolved )
+ {
+ delete iWrittenText;
+ iWrittenText = iCurrentLocalizedString;
+ iCurrentLocalizedString = NULL;
+ }
+ return resolved;
+ }
+
+// -----------------------------------------------------------------------------
+// CVcXmlParser::ResolveTooltipTagL
+// Resolves the content of <tooltip>
+// -----------------------------------------------------------------------------
+//
+TBool CVcXmlParser::ResolveTooltipTagL( const TDesC8& aName,
+ const Xml::RAttributeArray& aAttributes )
+ {
+ RUBY_DEBUG_BLOCKL( "CVcXmlParser::ResolveTooltipTagL" );
+
+ TBool resolved = ResolveLocalizedTagL( aName, aAttributes, KXmlTooltipTag,
+ EXmlTooltip );
+ if ( resolved )
+ {
+ delete iTooltipText;
+ iTooltipText = iCurrentLocalizedString;
+ iCurrentLocalizedString = NULL;
+ }
+ return resolved;
+ }
+
+// -----------------------------------------------------------------------------
+// CVcXmlParser::ResolveLocalizedTagL
+// Resolves content of tag which contains localized data
+// -----------------------------------------------------------------------------
+//
+TBool CVcXmlParser::ResolveLocalizedTagL( const TDesC8& aName,
+ const Xml::RAttributeArray& aAttributes,
+ const TDesC8& aExpectedName,
+ TVcXmlTagNesting aTagEnum )
+ {
+ RUBY_DEBUG_BLOCKL( "CVcXmlParser::ResolveLocalizedTagL" );
+
+ TBool resolved( EFalse );
+ if ( aName == aExpectedName )
+ {
+ resolved = ETrue;
+ iXmlNesting.Append( aTagEnum );
+
+ resolved = GetLocalizedStringL( aAttributes, KXmlLocAttr );
+ }
+
+ return resolved;
+ }
+
+// -----------------------------------------------------------------------------
+// CVcXmlParser::ResolveExecutesTagL
+// Resolves the content of <executes>
+// -----------------------------------------------------------------------------
+//
+TBool CVcXmlParser::ResolveExecutesTagL( const TDesC8& aName,
+ const Xml::RAttributeArray& aAttributes )
+ {
+ RUBY_DEBUG_BLOCKL( "CVcXmlParser::ResolveExecutesTagL" );
+
+ TBool resolved( EFalse );
+
+ if ( aName == KXmlExecutesTag )
+ {
+ resolved = ETrue;
+ iXmlNesting.Append( EXmlExecutes );
+
+ iAppId = ResolveUidL( aAttributes );
+ if ( iAppId == KNullUid )
+ {
+ resolved = ResolveExeL( aAttributes );
+ }
+ }
+
+ return resolved;
+ }
+
+// -----------------------------------------------------------------------------
+// CVcXmlParser::ResolveCmdlineparamsTag
+// Resolves the content of <cmdlineparams>
+// -----------------------------------------------------------------------------
+//
+TBool CVcXmlParser::ResolveCmdlineparamsTag( const TDesC8& aName,
+ const Xml::RAttributeArray& /*aAttributes*/ )
+ {
+ TBool resolved( EFalse );
+
+ if ( aName == KXmlCmdlineparamsTag )
+ {
+ iXmlNesting.Append( EXmlCmdlineparams );
+ delete iParameters;
+ delete iParameters8;
+ iParameters = NULL;
+ iParameters8 = NULL;
+ resolved = ETrue;
+ }
+
+ return resolved;
+ }
+
+// -----------------------------------------------------------------------------
+// CVcXmlParser::ResolveIconTagL
+// Resolves the content of <icon>
+// -----------------------------------------------------------------------------
+//
+TBool CVcXmlParser::ResolveIconTagL( const TDesC8& aName,
+ const Xml::RAttributeArray& aAttributes )
+ {
+ RUBY_DEBUG_BLOCKL( "CVcXmlParser::ResolveIconTagL" );
+
+ TBool resolved( EFalse );
+
+ if ( aName == KXmlIconTag )
+ {
+ resolved = ETrue;
+ iXmlNesting.Append( EXmlIcon );
+
+ iIcon = ResolveUidL( aAttributes );
+ if ( iIcon == KNullUid )
+ {
+ resolved = EFalse;
+ }
+ }
+
+ return resolved;
+ }
+
+// -----------------------------------------------------------------------------
+// CVcXmlParser::Find16ValueL
+// Finds a certain attribute and returns its value as unicode
+// -----------------------------------------------------------------------------
+//
+const TDesC& CVcXmlParser::Find16ValueL( const TDesC8& aName,
+ const Xml::RAttributeArray& aAttributes )
+ {
+ RUBY_DEBUG_BLOCKL( "CVcXmlParser::Find16ValueL" );
+
+ delete iAttributeValue;
+ iAttributeValue = NULL;
+
+ iAttributeValue = CnvUtfConverter::ConvertToUnicodeFromUtf8L( Find8ValueL( aName, aAttributes ) );
+
+ return *iAttributeValue;
+ }
+
+// -----------------------------------------------------------------------------
+// CVcXmlParser::Find8ValueL
+// Finds a certain attribute and returns its value as utf-8
+// -----------------------------------------------------------------------------
+//
+const TDesC8& CVcXmlParser::Find8ValueL( const TDesC8& aName,
+ const Xml::RAttributeArray& aAttributes )
+ {
+ RUBY_DEBUG_BLOCKL( "CVcXmlParser::Find8ValueL" );
+
+ // Loop through attribute list
+ for ( TInt iCounter = 0 ; iCounter < aAttributes.Count() ; iCounter++ )
+ {
+ HBufC8* name = ToLowercaseLC( aAttributes[iCounter].Attribute().LocalName().DesC() );
+
+ if ( name->Des() == aName )
+ {
+ CleanupStack::PopAndDestroy( name );
+
+ return aAttributes[iCounter].Value().DesC();
+ }
+ CleanupStack::PopAndDestroy( name );
+ }
+
+ return KNullDesC8;
+ }
+
+// -----------------------------------------------------------------------------
+// CVcXmlParser::ResetVCommandFolder
+// Destroys the data of one voice command folder
+// -----------------------------------------------------------------------------
+//
+void CVcXmlParser::ResetVCommandFolder()
+ {
+ delete iFolder;
+ iFolder = HBufC16::New( 0 );
+
+ delete iFolderTitle;
+ iFolderTitle = HBufC16::New( 0 );
+
+ delete iFolderIconFile;
+ iFolderIconFile = HBufC16::New( 0 );
+
+ iFolderIconIndex = -1;
+
+ ResetVCommandInfo();
+ }
+
+// -----------------------------------------------------------------------------
+// CVcXmlParser::ResetVCommandInfo
+// Destroys the data of one voice command
+// -----------------------------------------------------------------------------
+//
+void CVcXmlParser::ResetVCommandInfo()
+ {
+ delete iWrittenText;
+ iWrittenText = NULL;
+ delete iSpokenText;
+ iSpokenText = NULL;
+ delete iTooltipText;
+ iTooltipText = NULL;
+ delete iParameters;
+ iParameters = NULL;
+ delete iParameters8;
+ iParameters8 = NULL;
+ delete iAppName;
+ iAppName = NULL;
+
+ iAppId = KNullUid;
+ iIcon = KNullUid;
+
+ iStartImmediately = EFalse;
+ iUserCanModify = ETrue;
+ }
+
+// -----------------------------------------------------------------------------
+// CVcXmlParser::CheckVoiceCommmandData
+// Checks if all mandatory data for one voice command is available and makes
+// callback based on that
+// -----------------------------------------------------------------------------
+//
+void CVcXmlParser::CheckVoiceCommmandData()
+ {
+ if ( iWrittenText && ( iAppId != KNullUid || iAppName ) )
+ {
+ RUBY_DEBUG0( "CVcXmlParser::CheckVoiceCommmandData(): All required data for voice command found ok" );
+
+ // folder icon file is optional
+ // if it is not present, reference to KNullDesC should be passed
+ const TDesC* pFolderIconFile =iFolderIconFile;
+ if( !pFolderIconFile )
+ {
+ pFolderIconFile = &KNullDesC;
+ }
+
+ iObserver.MvcxpoVoiceCommandFound( *iWrittenText, *iSpokenText,
+ *iTooltipText, *iFolder, *iFolderTitle,
+ *iParameters, iIcon,
+ iAppId, *iAppName,
+ iStartImmediately, iUserCanModify,
+ *pFolderIconFile, iFolderIconIndex );
+ }
+ else
+ {
+ RUBY_DEBUG0( "VC XML ERROR: Mandatory data not found for Voice Command" );
+ }
+ }
+
+// -----------------------------------------------------------------------------
+// CVcXmlParser::GetLocalizedStringL
+// Reads localized string from resource file
+// -----------------------------------------------------------------------------
+//
+TBool CVcXmlParser::GetLocalizedStringL( const Xml::RAttributeArray& aAttributes,
+ const TDesC8& aAttributeName )
+ {
+ RUBY_DEBUG_BLOCKL( "CVcXmlParser::GetLocalizedStringL" );
+
+ TBool resolved( EFalse );
+ iCurrentLocalizedString = NULL;
+
+ // Resource file object should have been initialized
+ if ( !iResource )
+ {
+ return resolved;
+ }
+
+ // locIndex is key to the localized resource file
+ TPtrC8 locAttr( aAttributeName );
+ TPtrC locIndex = Find16ValueL( locAttr, aAttributes );
+
+ if ( locIndex != KNullDesC )
+ {
+ HBufC* command = NULL;
+ // Find string from loc file based on key
+ TRAPD( error, command = &iResource->GetCommandL( locIndex ) );
+ if ( error == KErrNone )
+ {
+ // Make a copy of localized string
+ TPtr des = command->Des();
+ delete iCurrentLocalizedString;
+ iCurrentLocalizedString = des.Alloc();
+ resolved = ETrue;
+ }
+ else
+ {
+ resolved = EFalse;
+ iCurrentLocalizedString = NULL;
+ RUBY_DEBUG0( "VC XML ERROR: Cannot resolve localized string" );
+ User::Leave( KErrGeneral );
+ }
+ }
+
+ return resolved;
+ }
+
+// -----------------------------------------------------------------------------
+// CVcXmlParser::ResolveUidL
+// Resolves the content of uid="0x1234567" attribute
+// -----------------------------------------------------------------------------
+//
+TUid CVcXmlParser::ResolveUidL( const Xml::RAttributeArray& aAttributes )
+ {
+ RUBY_DEBUG_BLOCKL( "CVcXmlParser::ResolveUidL" );
+
+ _LIT( KHexIdentifierLowercase, "0x" );
+ _LIT( KHexIdentifierUppercase, "0X" );
+ const TInt KHexIndentifierLength = 2;
+
+ TUid newUid( KNullUid );
+
+ TPtrC uidDes = Find16ValueL( KXmlUidAttr, aAttributes );
+
+ if ( uidDes != KNullDesC )
+ {
+ TPtrC ptr( uidDes );
+ // Check if string starts with 0x or 0X
+ if ( ( uidDes.Find( KHexIdentifierLowercase ) == 0 ) ||
+ ( uidDes.Find( KHexIdentifierUppercase ) == 0 ) )
+ {
+ ptr.Set( uidDes.Right( uidDes.Length() - KHexIndentifierLength ) );
+ }
+
+ // Do conversion from string to number
+ TLex lex( ptr );
+ TInt64 intUid( 0 );
+ TInt error = lex.Val( intUid, EHex );
+ newUid.iUid = intUid;
+ }
+
+ return newUid;
+ }
+
+// -----------------------------------------------------------------------------
+// CVcXmlParser::ResolveExeL
+// Resolves the content of exe="name.exe" attribute
+// -----------------------------------------------------------------------------
+//
+TBool CVcXmlParser::ResolveExeL( const Xml::RAttributeArray& aAttributes )
+ {
+ RUBY_DEBUG_BLOCKL( "CVcXmlParser::ResolveExeL" );
+
+ TBool resolved( EFalse );
+
+ TPtrC nameDes = Find16ValueL( KXmlExeAttr, aAttributes );
+ if ( nameDes != KNullDesC )
+ {
+ delete iAppName;
+ iAppName = NULL;
+
+ iAppName = HBufC::NewL( nameDes.Length() );
+ TPtr namePtr = iAppName->Des();
+ namePtr.Copy( nameDes );
+
+ resolved = ETrue;
+ }
+
+ return resolved;
+ }
+
+// -----------------------------------------------------------------------------
+// CVcXmlParser::ToLowercaseLC
+// Converts given string to lowercase
+// -----------------------------------------------------------------------------
+//
+HBufC8* CVcXmlParser::ToLowercaseLC( const TDesC8& aString )
+ {
+ // RUBY_DEBUG0( "CVcXmlParser::ToLowercaseLC START" );
+
+ // Convert string to lowercase
+ HBufC8* string = HBufC8::NewL( aString.Length() );
+ CleanupStack::PushL( string );
+ TPtr8 des = string->Des();
+ des.Copy( aString );
+ des.LowerCase();
+
+ //RUBY_DEBUG0( "CVcXmlParser::ToLowercaseLC EXIT" );
+
+ return string;
+ }
+
+// -----------------------------------------------------------------------------
+// Reads the iconfile attribute and constructs the file name or
+// sets it to NULL
+//
+// @params aAttributes List of XML attributes
+// @return ETrue if resolved successfully, EFalse otherwise
+// -----------------------------------------------------------------------------
+TBool CVcXmlParser::ResolveFolderIconFileL( const Xml::RAttributeArray& aAttributes )
+ {
+ RUBY_DEBUG_BLOCKL( "CVcXmlParser::ResolveFolderIconFileL" );
+
+ TBool resolved( EFalse );
+ delete iFolderIconFile;
+ iFolderIconFile = NULL;
+
+ TPtrC nameDes = Find16ValueL( KXmlFolderIconFileAttr, aAttributes );
+ if ( nameDes != KNullDesC )
+ {
+ iFolderIconFile = HBufC::NewL( nameDes.Length() );
+ TPtr folderIconFilePtr = iFolderIconFile->Des();
+ folderIconFilePtr.Copy( nameDes );
+
+ resolved = ETrue;
+ }
+
+ return resolved;
+
+ }
+
+// -----------------------------------------------------------------------------
+// Reads the iconindex attribute and stores the index or sets it to 0
+//
+// @params aAttributes List of XML attributes
+// @return ETrue if resolved successfully, EFalse otherwise
+// -----------------------------------------------------------------------------
+TInt CVcXmlParser::ResolveFolderIconIndexL( const Xml::RAttributeArray& aAttributes )
+ {
+ RUBY_DEBUG_BLOCKL( "CVcXmlParser::ResolveFolderIconIndexL" );
+
+ TInt index = -1;
+
+ TPtrC indexDes = Find16ValueL( KXmlFolderIconIndexAttr, aAttributes );
+
+ if ( indexDes != KNullDesC )
+ {
+ TPtrC ptr( indexDes );
+
+ // Do conversion from string to number
+ TLex lex( ptr );
+ TInt error = lex.Val( index );
+ if( error != KErrNone )
+ {
+ RUBY_ERROR1( "Converting icon index from string to int resulted in [%d]", error );
+ index = -1;
+ }
+ }
+
+ return index;
+ }
+
+// End of File