--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/messagingfw/wappushfw/SISLContentHandlers/src/CMsgParser.cpp Mon Jan 18 20:36:02 2010 +0200
@@ -0,0 +1,408 @@
+// Copyright (c) 2000-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:
+//
+
+#include <f32file.h>
+#include <xml/documentparameters.h>
+#include <xml/taginfo.h>
+#include <xml/attribute.h>
+
+using namespace Xml;
+
+#include <xml/xmlparsererrors.h>
+#include <xml/xmlframeworkerrors.h>
+
+// User Include
+#include "CMsgParser.h"
+#include "errorcodes.h"
+//text SL MIME type
+_LIT(KSLTextContentType, "text/vnd.wap.sl");
+_LIT(KSITextContentType, "text/vnd.wap.si");
+
+_LIT8(KXmlParserDataType, "text/xml");
+_LIT8(KWbxmlParserDataType, "text/wbxml");
+
+/**
+ * Constructor
+ * Copy CPushMessage pointer for reference during parse operations
+ */
+CMessageParser::CMessageParser ( CPushMessage& aPushMessage,
+ MWAPElementHandler& aElementHandler,
+ const TStringTable* aTagsTable,
+ const TStringTable* aAttributeTable,
+ const TStringTable* aAttributeValueTable )
+ : iPushMessage ( aPushMessage ),
+ iElementHandler ( aElementHandler ),
+ iTagsTable ( aTagsTable ),
+ iAttributeTable ( aAttributeTable ),
+ iAttributeValueTable ( aAttributeValueTable )
+ {
+ }
+
+/**
+*/
+CMessageParser::~CMessageParser()
+ {
+ delete iParser;
+ }
+
+/**
+
+*/
+CMessageParser* CMessageParser::NewL( CPushMessage& aPushMessage,
+ MWAPElementHandler& aElementHandler,
+ const TStringTable* aTagsTable,
+ const TStringTable* aAttributeTable,
+ const TStringTable* aAttributeValueTable )
+ {
+ CMessageParser* self = new ( ELeave ) CMessageParser ( aPushMessage, aElementHandler, aTagsTable, aAttributeTable, aAttributeValueTable );
+ CleanupStack::PushL ( self );
+ self->ConstructL ();
+ CleanupStack::Pop ( self );
+ return ( self );
+ }
+
+/**
+
+*/
+void CMessageParser::ConstructL()
+ {
+ LoadPluginL ();
+ RStringPool& pool = StringPool ();
+ pool.OpenL ( *iTagsTable );
+ pool.OpenL ( *iAttributeTable );
+ pool.OpenL ( *iAttributeValueTable );
+ }
+
+void CMessageParser::LoadPluginL ()
+ {
+ TPtrC contentType;
+ iPushMessage.GetContentType ( contentType );
+ TBool xml = ETrue;
+ if ( contentType.CompareF ( KSLTextContentType ) && contentType.CompareF ( KSITextContentType ) )
+ {
+ xml = EFalse;
+ }
+
+ iParser = CParser::NewL ( ( xml ) ? KXmlParserDataType() : KWbxmlParserDataType(), *this );
+ }
+/**
+
+*/
+TInt CMessageParser::ParseMessageL ()
+ {
+ // Begin parsing
+ iParser->ParseBeginL ();
+
+ // Get the message body and do parsing.
+ TPtrC8 msgBody;
+ iPushMessage.GetMessageBody ( msgBody );
+
+ iParser->ParseL ( msgBody );
+
+ // End parsing
+ iParser->ParseEndL ();
+
+ return KErrNone;
+ }
+
+RStringPool& CMessageParser::StringPool ()
+ {
+ return iParser->StringPool ();
+ }
+
+void CMessageParser::OnStartDocumentL ( const Xml::RDocumentParameters& /* aDocParam */, TInt aErrorCode )
+ {
+ User::LeaveIfError ( MapToWapXMLError ( aErrorCode ) );
+ }
+
+void CMessageParser::OnEndDocumentL ( TInt aErrorCode )
+ {
+ User::LeaveIfError ( MapToWapXMLError ( aErrorCode ) );
+ }
+
+void CMessageParser::OnStartElementL ( const Xml::RTagInfo& aElement, const Xml::RAttributeArray& aAttributes, TInt aErrorCode )
+ {
+ User::LeaveIfError( MapToWapXMLError ( aErrorCode ) );
+
+ TInt nAttributes = aAttributes.Count();
+ RString tag = aElement.LocalName();
+ CheckTagInTableL ( tag );
+
+ for ( TInt i = 0; i < nAttributes; ++i )
+ {
+ const RAttribute& attribute = aAttributes[i];
+ const RTagInfo& nameInfo = attribute.Attribute();
+
+ RString attr = nameInfo.LocalName();
+ RString attributeValue = attribute.Value();
+ CheckAttributeValuePairL ( attr, attributeValue );
+ iElementHandler.HandleElementL ( tag, attr, attributeValue );
+ }
+ }
+
+void CMessageParser::OnEndElementL ( const Xml::RTagInfo& /* aElement */, TInt aErrorCode )
+ {
+ User::LeaveIfError ( MapToWapXMLError ( aErrorCode ) );
+ }
+
+void CMessageParser::OnContentL ( const TDesC8& aBytes, TInt aErrorCode )
+ {
+ User::LeaveIfError ( MapToWapXMLError ( aErrorCode ) );
+ iElementHandler.HandleContentL ( aBytes );
+ }
+
+void CMessageParser::OnStartPrefixMappingL ( const RString& /* aPrefix */, const RString& /* aUri */, TInt aErrorCode )
+ {
+ User::LeaveIfError ( MapToWapXMLError ( aErrorCode ) );
+ }
+
+void CMessageParser::OnEndPrefixMappingL ( const RString& /* aPrefix */, TInt aErrorCode )
+ {
+ User::LeaveIfError ( MapToWapXMLError ( aErrorCode ) );
+ }
+
+void CMessageParser::OnIgnorableWhiteSpaceL ( const TDesC8& /* aBytes */, TInt aErrorCode )
+ {
+ User::LeaveIfError ( MapToWapXMLError ( aErrorCode ) );
+ }
+
+void CMessageParser::OnSkippedEntityL ( const RString& /* aName */, TInt aErrorCode )
+ {
+ User::LeaveIfError ( MapToWapXMLError ( aErrorCode ) );
+ }
+
+void CMessageParser::OnProcessingInstructionL ( const TDesC8& /* aTarget */, const TDesC8& /* aData */, TInt aErrorCode )
+ {
+ User::LeaveIfError ( MapToWapXMLError ( aErrorCode ) );
+ }
+
+void CMessageParser::OnError ( TInt aErrorCode )
+ {
+ iLastError = MapToWapXMLError ( aErrorCode );
+ }
+
+TAny* CMessageParser::GetExtendedInterface ( const TInt32 /* aUid */ )
+ {
+ return NULL;
+ }
+
+void CMessageParser::CheckTagInTableL ( const RString& aTag )
+ {
+ // Check the tag is appearing in the tags table
+ TInt index = aTag.Index ( *iTagsTable );
+
+ if ( ( index == KErrNotFound ) || ( iTagPosition != index ) )
+ {
+ // This tag name does not appear in tags table or tag is not in the right position as in DTD.
+ // Tag is illegal or shouldn't appear or not in the expected position in XML content .
+ User::Leave ( EWapErrXmlLibIllegalTagName );
+ }
+ ++iTagPosition; // Increment the tag position.
+ }
+
+void CMessageParser::CheckAttributeValuePairL ( const RString& aAttribute, const RString& aAttributeValue )
+{
+ // Check the attribute is appearing in attribute table.
+ TInt attributeIndex = aAttribute.Index ( *iAttributeTable );
+
+ if ( attributeIndex == KErrNotFound )
+ {
+ User::Leave ( EWapErrXmlLibMissingRequiredAttribute );
+ }
+ RStringPool& pool = iParser->StringPool();
+ // Loop it around the attribute & value table. Value can be pre-defined and specific
+ for ( TInt i = attributeIndex; i < iAttributeTable->iCount; ++i )
+ {
+ // Check the attribute matches
+ RString attribute = pool.String ( i, *iAttributeTable );
+ if ( attribute != aAttribute )
+ {
+ break;
+ }
+
+ RString attributeVal = pool.String ( i, *iAttributeValueTable );
+ if ( ( attributeVal.DesC().Length() == 0 ) || ( attributeVal == aAttributeValue ) )
+ {
+ // Attribute takes any attribute value or attribute value mataches with the table values.
+ // Attribute value is valid.
+ return;
+ }
+ }
+
+ User::Leave ( EWapErrXmlLibIllegalAttributeValue );
+ }
+
+TInt CMessageParser::LastError ()
+ {
+ return iLastError;
+ }
+
+// Map the generic XML parser code to WAP XML errors. Description of the error code
+// has taken from expat.
+TInt CMessageParser::MapToWapXMLError ( TInt aXmlErrorCode )
+ {
+
+ TInt errorCode = aXmlErrorCode;
+
+ switch ( aXmlErrorCode )
+ {
+ case EXmlParserError:
+ case EXmlSyntax:
+ errorCode = EWapErrGeneral;
+ break;
+ // The document contains no elements
+ // (XML requires all documents to contain exactly one top-level element)..
+ case EXmlNoElements:
+ errorCode = EWapErrXmlLibMissingDocumentRootNode;
+ break;
+
+ // Raised when an input byte could not properly be assigned to a character;
+ // for example, a NUL byte (value 0) in a UTF-8 input stream.
+ case EXmlInvalidToken:
+ errorCode = EWapErrXmlLibIllegalTagName;
+ break;
+
+ // Some token (such as a start tag) was not closed before the end of the stream or
+ // the next token was encountered.
+ case EXmlUnclosedToken:
+ // An end tag did not match the innermost open start tag.
+ case EXmlTagMismatch:
+ errorCode = EWapErrXmlLibEndTagMismatch;
+ break;
+
+ // An incomplete character was found in the input.
+ case EXmlPartialChar:
+ // A character reference referred to a character which is illegal in XML
+ // (for example, character 0, or `�').
+ case EXmlBadCharRef:
+ errorCode = EWapErrXmlLibInvalidCharacterReference;
+ break;
+
+ // An attribute was used more than once in a start tag.
+ case EXmlDuplicateAttribute:
+ errorCode = EWapErrXmlLibInvalidAttributeDeclaration;
+ break;
+
+ // Something other than whitespace occurred after the document element.
+ case EXmlJunkAfterDocElement:
+ // A parameter entity reference was found where it was not allowed.
+ case EXmlPeRef:
+ errorCode = EWapErrDocumentCorrupted;
+ break;
+
+ // A reference was made to a entity which was not defined.
+ case EXmlUndefinedEntity:
+ // An entity reference contained another reference to the same entity; possibly via a
+ // different name, and possibly indirectly.
+ case EXmlRecursiveEntity:
+ case EXmlAsyncEntity:
+ // An entity reference in an attribute value referred to an external entity instead of an internal entity.
+ case EXmlAttributeExternalEntityRef:
+ case EXmlExternalEntityHandling:
+ errorCode = EWapErrXmlLibUnknownEntityReference;
+ break;
+
+ // An entity reference referred to an entity which was declared with a notation,
+ // so cannot be parsed.
+ case EXmlBinaryEntityRef:
+ errorCode = EWapErrDocumentCorrupted;
+ break;
+
+ // An XML declaration was found somewhere other than the start of the input data.
+ case EXmlMisplacedPi:
+ case EXmlIncorrectEncoding:
+ errorCode = EWapErrXmlLibInvalidDocument;
+ break;
+ // The document encoding is not supported by Expat.
+ case EXmlUnknownEncoding:
+ errorCode = EWapErrUnknownDocument;
+ break;
+
+ // A CDATA marked section was not closed.
+ case EXmlUnclosedCdata:
+ errorCode = EWapErrXmlLibMissingCDATASectionEndTag;
+ break;
+
+// The parser determined that the document was not ``standalone''
+ // though it declared itself to be in the XML declaration, and the NotStandaloneHandler
+ // was set and returned 0.
+ case EXmlNotStandalone:
+ case EXmlUnexpectedState:
+ case EXmlEntityDeclInPe:
+ errorCode = EWapErrUnknownDocument;
+ break;
+
+ case EXmlDtdRequired:
+ errorCode = EWapErrDTDUnavailable;
+ break;
+
+ // A behavioral change was requested after parsing started that can only be changed
+ // before parsing has started. This is (currently) only raised by UseForeignDTD().
+ case EXmlFeatureLockedWhileParsing:
+ errorCode = EWapErrGeneral;
+ break;
+
+ // Xml framework errors
+ case KErrXmlStringDictionaryPluginNotFound:
+ case KErrXmlParserPluginNotFound:
+ case KErrXmlGeneratorPluginNotFound:
+ case KErrXmlPluginNotFound:
+ errorCode = EWapErrPluginNotFound;
+ break;
+
+ case KErrXmlBadCharacterConversion:
+ case KErrXmlUnsupportedCharacterSet:
+ case KErrXmlUnavailableCharacterSet:
+ errorCode = EWapErrXmlLibInvalidCharacterReference;
+ break;
+
+ // MStringDictionary errors ( mainly wbxml errors )
+ case KErrXmlUnsupportedElement:
+ errorCode = EWapErrXmlLibIllegalTagName;
+ break;
+
+ case KErrXmlUnsupportedAttribute:
+ errorCode = EWapErrXmlLibMissingRequiredAttribute;
+ break;
+
+ case KErrXmlUnsupportedAttributeValue:
+ errorCode = EWapErrXmlLibIllegalAttributeValue;
+ break;
+
+ case KErrXmlMissingStringDictionary:
+ errorCode = EWapErrXmlLibMissingDocument;
+ break;
+
+ case KErrXmlUnsupportedDocumentVersion:
+ errorCode = EWapErrXmlLibInvalidDocumentStructure;
+ break;
+
+ case KErrXmlDocumentCorrupt:
+ errorCode = EWapErrDocumentCorrupted;
+ break;
+
+ case KErrXmlStringPoolTableNotFound:
+ case KErrXmlBadIndex:
+ case KErrXmlUnsupportedExtInterface:
+ case KErrXmlLast:
+ errorCode = EWapErrGeneral;
+ break;
+
+ default:
+ // Do nothing. any other kind of error.
+ break;
+ }
+ return errorCode;
+ }