diff -r 000000000000 -r 8e480a14352b messagingfw/wappushfw/ROContentHandler/src/MessageComposer.cpp --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/messagingfw/wappushfw/ROContentHandler/src/MessageComposer.cpp Mon Jan 18 20:36:02 2010 +0200 @@ -0,0 +1,417 @@ +// Copyright (c) 2006-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 +#include +#include +#include + +using namespace Xml; + +// System Include +//For base64 encoding +#include +#include +#include +#include + +// User Include +#include "MessageComposer.h" +#include "errorcodes.h" + +const TInt KXmlBufferlength = 128; +//text DRM MIME type +_LIT(KDRMTextContentType, "application/vnd.oma.drm.rights+xml"); + +//prefix and suffix to be appended. +_LIT8(KXmlParserDataType, "text/xml"); +_LIT8(KWbxmlParserDataType, "text/wbxml"); +_LIT8(KOpeningBracket, "<"); +_LIT8(KClosingBracket, ">"); +_LIT8(KOpeningEndBracket, "ConstructL (); + CleanupStack::Pop ( self ); + return ( self ); + } + +/** +*/ +void CMessageComposer::ConstructL() + { + iXmlBuf.CreateL(KXmlBufferlength); + LoadPluginL (); + } + +/* +* Load the plugin based on incoming message (XML or WBXML plugin) +*/ +void CMessageComposer::LoadPluginL () + { + TPtrC contentType; + iPushMessage.GetContentType ( contentType ); + iParser = CParser::NewL ( ( contentType.CompareF ( KDRMTextContentType ) ) ? + KWbxmlParserDataType() : KXmlParserDataType(), *this ); + } + +/** + +*/ +const TDesC8& CMessageComposer::ParseMessageL () + { + // Begin parsing + iParser->ParseBeginL (); + + // Get the message body and do parsing. + TPtrC8 msgBody; + if(iPushMessage.GetMessageBody ( msgBody )) + { + iParser->EnableFeature ( ERawContent ); + iParser->ParseL ( msgBody ); + } + else + { + //Leave with KErrNotFound error code as message body not found + User::Leave ( KErrNotFound ); + } + + // End parsing + iParser->ParseEndL (); + + return iXmlBuf; + } + +RStringPool& CMessageComposer::StringPool () + { + return iParser->StringPool (); + } + +void CMessageComposer::OnStartDocumentL ( const Xml::RDocumentParameters& /*aDocParam*/ , TInt aErrorCode ) + { + User::LeaveIfError ( MapToWapXMLError ( aErrorCode ) ); + } + +void CMessageComposer::OnEndDocumentL ( TInt aErrorCode ) + { + User::LeaveIfError ( MapToWapXMLError ( aErrorCode ) ); + } + +void CMessageComposer::OnStartElementL ( const Xml::RTagInfo& aElement, const Xml::RAttributeArray& aAttributes, TInt aErrorCode ) + { + User::LeaveIfError( MapToWapXMLError ( aErrorCode ) ); + + if(aElement.LocalName().DesC().Compare(_L8("ds:KeyValue")) == 0) + { + iIsKeyValue = ETrue; + } + + //Append '<' before the element + AppendDataL ( KOpeningBracket ); + //Append the element + AppendDataL ( aElement.LocalName().DesC() ); + + //Now append all the attributes and attribute values in loop + TInt nAttributes = aAttributes.Count(); + for ( TInt i = 0; i < nAttributes; ++i ) + { + const RAttribute& attribute = aAttributes[i]; + const RTagInfo& nameInfo = attribute.Attribute(); + //Append a blanck space before appending attribute name + AppendDataL ( KSpace ); + //Append the attribute name + AppendDataL ( nameInfo.LocalName().DesC() ); + //Append '="' before appending attribute value + AppendDataL ( KOpeningQuote ); + //Append attribue Value + AppendDataL ( attribute.Value().DesC() ); + //Append '"' after the attribute value + AppendDataL ( KClosingQuote ); + }//End of for loop, appended all attribures of this element + //Append '>' after the element + AppendDataL ( KClosingBracket ); + } + +void CMessageComposer::OnEndElementL ( const Xml::RTagInfo& aElement , TInt aErrorCode ) + { + User::LeaveIfError ( MapToWapXMLError ( aErrorCode ) ); + + AppendDataL ( KOpeningEndBracket ); + AppendDataL ( aElement.LocalName().DesC() ); + AppendDataL ( KClosingBracket ); + } + +void CMessageComposer::OnContentL ( const TDesC8& aBytes, TInt aErrorCode ) + { + User::LeaveIfError ( MapToWapXMLError ( aErrorCode ) ); + + if(iIsKeyValue) + { + // Got to base64 encode the 128-bit encryption key. + iIsKeyValue = EFalse; + TBase64 codec; + TInt length = aBytes.Length(); + // Calculate the length of the base64 encoded key and create a buffer of that length. + HBufC8* encodedBytes = HBufC8::NewLC(((length%3)>0)?((length/3)+length+3):((length/3)+length+2)); + TPtr8 encodedBytesPtr(encodedBytes->Des()); + codec.Encode(aBytes, encodedBytesPtr); + AppendDataL(*encodedBytes); + CleanupStack::PopAndDestroy(encodedBytes); + } + else + { + //Append the content. + AppendDataL ( aBytes ); + } + } + +void CMessageComposer::OnStartPrefixMappingL ( const RString& /* aPrefix */, const RString& /* aUri */, TInt aErrorCode ) + { + User::LeaveIfError ( MapToWapXMLError ( aErrorCode ) ); + } + +void CMessageComposer::OnEndPrefixMappingL ( const RString& /* aPrefix */, TInt aErrorCode ) + { + User::LeaveIfError ( MapToWapXMLError ( aErrorCode ) ); + } + +void CMessageComposer::OnIgnorableWhiteSpaceL ( const TDesC8& /* aBytes */, TInt aErrorCode ) + { + User::LeaveIfError ( MapToWapXMLError ( aErrorCode ) ); + } + +void CMessageComposer::OnSkippedEntityL ( const RString& /* aName */, TInt aErrorCode ) + { + User::LeaveIfError ( MapToWapXMLError ( aErrorCode ) ); + } + +void CMessageComposer::OnProcessingInstructionL ( const TDesC8& /* aTarget */, const TDesC8& /* aData */, TInt aErrorCode ) + { + User::LeaveIfError ( MapToWapXMLError ( aErrorCode ) ); + } + +void CMessageComposer::OnError ( TInt aErrorCode ) + { + iLastError = MapToWapXMLError ( aErrorCode ); + } + +TAny* CMessageComposer::GetExtendedInterface ( const TInt32 /* aUid */ ) + { + return NULL; + } + +TInt CMessageComposer::LastError () + { + return iLastError; + } + +void CMessageComposer::AppendDataL ( const TDesC8& aData ) + { + TInt xmlBufMaxLen = iXmlBuf.MaxLength (); + TInt xmlBufLen = iXmlBuf.Length (); + TInt dataLen = aData.Length (); + if ( xmlBufMaxLen < ( xmlBufLen + dataLen ) ) + { + // Need to allocate more space. + TInt lenToAllocate = (dataLen > KXmlBufferlength) ? dataLen : KXmlBufferlength; + iXmlBuf.ReAllocL ( xmlBufMaxLen + lenToAllocate ); + } + iXmlBuf.Append ( aData ); + } + +// Map the generic XML parser code to WAP XML errors. Description of the error code +// has taken from expat. +TInt CMessageComposer::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; + }