--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/IMPSengine/messageencoder/wbxml/src/ImpsEncodeWbXml.cpp Thu Dec 17 08:41:52 2009 +0200
@@ -0,0 +1,1400 @@
+/*
+* Copyright (c) 2003 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: Imps engine wbxml message encoder
+*
+*
+*/
+
+
+// INCLUDE FILES
+#include <e32std.h>
+#include <apparc.h>
+#include <s32mem.h>
+#include <utf.h>
+#include <e32math.h>
+#include <miutconv.h>
+//#include <mentact.h>
+
+#include "ImpsWbXmlData.h"
+#include "ImpsEncodewbxml.h"
+#include "ImpsDataAccessorapi.h"
+#include "ImpsErrors.h"
+#include "Imps_1_1_Tokens.h"
+#include "Imps_1_2_Tokens.h"
+#include "ImpsWbXmlCommon.h"
+#include "ImpsCspDtd.h"
+#include "ImpsUtils.h"
+#include "ImpsServices.h"
+#include "ImpsVariantAPI.h"
+#include "impsfields.h"
+#include "ImpsDataUtils.h"
+
+// ================= LOCAL FUNCTIONS ====================
+
+// ================= MEMBER FUNCTIONS =======================
+
+// C++ default constructor can NOT contain any code, that
+// might leave.
+//
+CImpsEncodeWbXml::CImpsEncodeWbXml( ):
+ iCspVersion( EImpsCspVersion11 )
+ {
+
+ }
+
+// default constructor can leave.
+void CImpsEncodeWbXml::ConstructL()
+ {
+
+ iElementValue = HBufC::NewL(KImpsWbXmlMaxStringLength);
+ iStoreValue = HBufC8::NewL(KImpsWbXmlMaxStringLength);
+
+ // create handler for wbxml data
+ iWbXmlData = CImpsWbXmlData::NewL( );
+
+ iCurrentDictionary = iDictionaryCount = 0;
+ iDictionaries[iDictionaryCount++] =
+ (NW_WBXML_Dictionary_s*)&NW_Imps_1_1_WBXMLDictionary;
+ iDictionaries[iDictionaryCount++] =
+ (NW_WBXML_Dictionary_s*)&NW_Imps_1_2_WBXMLDictionary;
+ if(NW_WBXML_Dictionary_initialize (iDictionaryCount,iDictionaries) != NW_STAT_SUCCESS)
+ {
+ User::Leave(KImpsErrorEncode);
+ }
+
+ // PEC in use ?
+ CImpsVariant* dpb = CImpsVariant::NewLC();
+ if (dpb->IsFeatureSupportedL(EDpb))
+ {
+ iXmlUtils = CImpsXmlUtils::NewL( );
+ iPEC = ETrue;
+ }
+ else
+ {
+ iXmlUtils = NULL;
+ iPEC = EFalse;
+ }
+
+ CleanupStack::PopAndDestroy();
+
+ }
+
+// Two-phased constructor.
+CImpsEncodeWbXml* CImpsEncodeWbXml::NewL( )
+ {
+
+ CImpsEncodeWbXml* self = new (ELeave) CImpsEncodeWbXml( );
+ CleanupStack::PushL( self );
+ self->ConstructL();
+ CleanupStack::Pop();
+
+ return self;
+ }
+
+
+// Destructor
+CImpsEncodeWbXml::~CImpsEncodeWbXml()
+ {
+
+ delete iWbXmlData;
+ delete iElementValue;
+ delete iStoreValue;
+ delete iXmlUtils;
+ NW_WBXML_Dictionary_destroy();
+
+ }
+
+// ---------------------------------------------------------
+// CImpsEncodeXml::EncodeMessageL
+// wbxml message encoder main function, which provides API
+// class aImpsData contains message data,
+// encoded message is stored to aEncodeBuffer
+// ---------------------------------------------------------
+//
+void CImpsEncodeWbXml::EncodeMessageL(
+ MImpsDataAccessor& aImpsData,
+ CBufFlat& aEncodeBuffer)
+ {
+
+ // INIT BUFFERS
+ iImpsData = &aImpsData;
+ iEncodeBuffer = &aEncodeBuffer;
+
+ // CREATE EMPTY DOM DOCUMENT TREE
+ NW_TinyDom_Handle_t handle;
+
+ // set up the version related things
+ iCspVersion = iImpsData->GetImpsFields()->CspVersion();
+
+ TInt cspVersion =
+ ((iCspVersion == EImpsCspVersion11)?KImpsWvCsp11PublicIdentifier:KImpsWvCsp12PublicIdentifier);
+
+
+ iCurrentDictionary =
+ ((iCspVersion == EImpsCspVersion11)? 0 : 1);
+
+ iDocument = NW_DOM_DocumentNode_createDocumentWithNumberPublicId(&handle,
+ KImpsWbXmlVersion,cspVersion,KImpsDefaultCharset,NW_TRUE,NW_TRUE);
+ if(!iDocument)
+ {
+ User::Leave(KImpsErrorEncode);
+ }
+
+ // check for possible buffer allocation failure
+ if(!iElementValue)
+ {
+ iElementValue = HBufC::NewL(KImpsWbXmlMaxStringLength);
+ }
+ if(!iStoreValue)
+ {
+ iStoreValue = HBufC8::NewL(KImpsWbXmlMaxStringLength);
+ }
+
+ // create key for data accessor
+ iAccessKey = iImpsData->NewKeyL();
+ iNameSpace = KImpsNameSpaceCspMessage;
+
+
+ // start building DOM document tree
+ TInt rcode = KErrNone;
+ TBufC<16> root(KImpsWvCspMessage);
+ TRAPD(error,rcode = EncodeElementL(root,iDocument,0))
+ if(error != KErrNone || rcode != KErrNone)
+ {
+
+ // FAILURE !
+ // delete DOM document
+ NW_DOM_DocumentNode_Delete(iDocument);
+ // delete access key
+ iAccessKey->Destroy( );
+ if(rcode != KErrNone)
+ {
+ User::Leave(rcode);
+ }
+ else
+ {
+ User::Leave(KImpsErrorEncode);
+ }
+ }
+ iAccessKey->Destroy( );
+
+ // ENCODE MESSAGE
+ TUint32 size = 0;
+ unsigned char *buffer = NULL;
+ NW_Encoder_t WbXmlEncoder;
+ if(NW_Encoder_encodeWBXML(&WbXmlEncoder,iDocument,NW_TRUE,&size,&buffer) != NW_STAT_SUCCESS)
+ {
+ // FAILURE !
+ // delete DOM document
+ NW_DOM_DocumentNode_Delete(iDocument);
+ if(buffer)
+ {
+ free(buffer);
+ }
+ User::Leave(KImpsErrorEncode);
+ }
+
+ // put the new public ID there
+// if (size >0)
+// {
+// buffer[1] = 0x10;
+// }
+
+ // copy message to aEncodeBuffer
+ if((TInt)size > iEncodeBuffer->Size())
+ {
+ iEncodeBuffer->Reset();
+ }
+
+ iEncodeBuffer->ResizeL(size);
+ iEncodeBuffer->Write(0,buffer,size);
+ free(buffer);
+
+ // delete DOM document
+ NW_DOM_DocumentNode_Delete(iDocument);
+
+ }
+
+// ---------------------------------------------------------
+// CImpsEncodeWbXml::ReadElementDeclaration
+// method reads elements DTD declaration
+// ---------------------------------------------------------
+//
+TPtrC CImpsEncodeWbXml::ReadElementDeclaration(TDesC &aElement)
+ {
+
+
+ TPtrC dtd;
+ if ( iCspVersion == EImpsCspVersion11 )
+ {
+ dtd.Set(KCspHeaderDtd11[NULL]);
+ }
+ else
+ {
+ dtd.Set(KCspHeaderDtd12[NULL]);
+ }
+
+ TInt i(0);
+ TInt count = 0;
+
+ if(iNameSpace == KImpsNameSpaceTransactionContent)
+ {
+ count = ((iCspVersion == EImpsCspVersion11)?KImpsTransactionDtd11Count:KImpsTransactionDtd12Count);
+ }
+ else if(iNameSpace == KImpsNameSpacePresenceSubList)
+ {
+ count = ((iCspVersion == EImpsCspVersion11)?KImpsPresenceDtd11Count:KImpsPresenceDtd12Count);
+ }
+ else
+ {
+ count = ((iCspVersion == EImpsCspVersion11)?KImpsHeaderDtd11Count:KImpsHeaderDtd12Count);
+ }
+ for(i=0;i<count;i++)
+ {
+ switch(iNameSpace)
+ {
+
+ case KImpsNameSpaceCspMessage:
+ if ( iCspVersion == EImpsCspVersion11 )
+ {
+ dtd.Set(KCspHeaderDtd11[i]);
+ }
+ else
+ {
+ dtd.Set(KCspHeaderDtd12[i]);
+ }
+ break;
+
+ case KImpsNameSpaceTransactionContent:
+ if ( iCspVersion == EImpsCspVersion11 )
+ {
+ dtd.Set(KCspContentDtd11[i]);
+ }
+ else
+ {
+ dtd.Set(KCspContentDtd12[i]);
+ }
+ break;
+
+ case KImpsNameSpacePresenceSubList:
+ if ( iCspVersion == EImpsCspVersion11 )
+ {
+ dtd.Set(KCspPresenceDtd11[i]);
+ }
+ else
+ {
+ dtd.Set(KCspPresenceDtd12[i]);
+ }
+ break;
+
+ }
+ if(dtd.Find(aElement) == 1 && dtd.Locate(' ') == (aElement.Length() + 1))
+ {
+ break;
+ }
+ }
+
+ return(dtd);
+
+ }
+
+// ---------------------------------------------------------
+// CImpsEncodeWbXml::EncodeElementL
+// method adds one node to DOM tree
+// ---------------------------------------------------------
+//
+TInt CImpsEncodeWbXml::EncodeElementL(TDesC &aElement, NW_DOM_ElementNode_t* aNode,TInt aIndex)
+ {
+
+ TBuf<sizeof(SImpsValueList)> valuebuf(sizeof(SImpsValueList));
+ SImpsValueList* valuelist = (SImpsValueList*)valuebuf.Ptr();
+
+ // Read element declaration
+ TPtrC element = ReadElementDeclaration(aElement);
+
+ // prepare child element list
+ ReadElementList(element,valuelist);
+
+ // Get element WBXML token
+ TBool extraelem = EFalse;
+ TInt token = ReadToken(element);
+
+ TInt elementcounter = 0;
+ TBool literal = false;
+
+ if(token == KErrNotFound)
+ {
+ // check for the extension token APIClient as it is not in the dictionary
+ if ( (aElement.CompareF(KImpsAPIClient))==0 )
+ {
+ literal = true;
+ }
+ else
+ {
+ extraelem = ETrue;
+ elementcounter = aIndex;
+ }
+ }
+
+ // Update data accessor key (root element is left out)
+ TInt primitive = KErrNone;
+ if(token != KImpsMessageRootElement && !extraelem)
+ {
+ if ( literal )
+ {
+ // add the APIClient key to accessor key
+ iAccessKey->AddL(CREATEKEY(EImpsKeyAPIClient,aIndex),EImpsKeyTypeIM);
+ }
+ else
+ {
+ primitive = SetDataAccessorKeyL(token,aIndex);
+ }
+ }
+
+ TInt rcode = KErrNotFound;
+ NW_DOM_ElementNode_t *node = NULL;
+ TInt exrcode = KErrNotFound;
+
+ if(iImpsData->CheckBranchExistenceL(iAccessKey) || extraelem)
+ {
+ if ( literal )
+ {
+ HBufC8* literalToken = HBufC8::NewL(aElement.Length()+1);// for the \0 at the end
+ CleanupStack::PushL(literalToken);
+ literalToken->Des().Copy(aElement);
+
+ // create an element node from string for extension element
+ NW_String_t* elementString = NW_String_new();
+ NW_String_initialize(elementString, (void*)literalToken->Des().PtrZ(), HTTP_utf_8);
+ node = NW_DOM_DocumentNode_createElementNode(iDocument, elementString);
+ NW_String_delete(elementString);
+
+ // literalToken has to be deleted as last because NW_String keeps the pointer
+ CleanupStack::PopAndDestroy(); // literalToken
+ }
+ else
+ {
+ node = NW_DOM_DocumentNode_createElementNodeByToken(iDocument,(TUint16)token);
+ }
+
+ if(node != NULL || extraelem)
+ {
+ if((rcode = EncodeAttributes(token,node)) == KErrNone || extraelem)
+ {
+ if(!(valuelist->Flags & KImpsValueListEmpty))
+ {
+ TPtrC value = ReadNextValue(valuelist,element);
+ if(value.Find(KPcData) != KErrNotFound)
+ {
+ // encode value
+ rcode = EncodeValueL(token,node,aIndex);
+ }
+ else
+ {
+ for(;;)
+ {
+ if(valuelist->Flags & KImpsValueListAlternative && !extraelem)
+ {
+ if(primitive == KErrNotFound)
+ {
+ TImpsKeyType type = EImpsKeyTypeIM;
+ iImpsData->RestoreAlternativeL(iAccessKey,primitive,aIndex,type);
+ }
+ // Get the element name string from the 1.2 dictionary as it has all the elements
+ // TPtrC elementName(KNullDesC);
+
+ TUint16* elementNamePtr = (TUint16*)NW_WBXML_Dictionary_getTagByFqToken((NW_Uint32)(2<<16)+primitive)->bytes;
+ if (elementNamePtr)
+ {
+ value.Set(elementNamePtr);
+ }
+ else
+ {
+ value.Set(KNullDesC);
+ }
+
+ //value.Set(iWbXmlData->GetDtdValue(token,primitive));
+ }
+ if(extraelem)
+ {
+ node = aNode;
+ }
+ rcode = EncodeElementL(value,node,elementcounter);
+ if(rcode == KErrNone && extraelem)
+ {
+ exrcode = KErrNone;
+ }
+ value.Set(FetchNextElement(valuelist,elementcounter,rcode,element,value));
+ if(rcode == KErrNotFound)
+ {
+ if(extraelem) rcode = exrcode;
+ else rcode = KErrNone;
+ break;
+ }
+ if(rcode == KImpsErrorEncode || rcode == KImpsErrorValidate)
+ {
+ if(extraelem)
+ {
+ rcode = KErrNotFound;
+ }
+ else
+ {
+ rcode = KImpsErrorValidate;
+ }
+ break;
+ }
+ }
+ }
+ }
+ if(rcode == KErrNone && !extraelem)
+ {
+ // append node to parent node
+ NW_Status_t status = NW_DOM_Node_appendChild((NW_TinyTree_Node_s*)aNode,node);
+ if(status != NW_STAT_SUCCESS)
+ {
+ rcode = KImpsErrorEncode;
+ }
+ }
+ }
+ else
+ {
+ rcode = KImpsErrorEncode;
+ }
+ }
+ else
+ {
+ rcode = KImpsErrorEncode;
+ }
+ }
+ else
+ {
+ if(token == KImpsWbXmlContentSize)
+ {
+ // special case, content size must be calculated
+ rcode = SetContentSizeL(token,aNode);
+ }
+ else
+ {
+ rcode = KErrNotFound;
+ }
+ }
+
+ // update data access key
+ if(!extraelem)
+ {
+ PopAccessKeyL(token);
+ }
+
+ return(rcode);
+ }
+
+// ---------------------------------------------------------
+// CImpsEncodeWbXml::SetContentSize
+// method counts message content size
+// ---------------------------------------------------------
+//
+TInt CImpsEncodeWbXml::SetContentSizeL(TInt aToken,NW_DOM_ElementNode_t* aNode)
+ {
+ iAccessKey->PopL(2);
+ iAccessKey->AddL(EImpsKeyContentData);
+
+ TInt size(0);
+ if ( TImpsDataUtils::GetContentDataTypeL( iImpsData, 0 ) == EImpsDataTypeDesc )
+ {
+ TDesC *p;
+ if ( iImpsData->RestoreDescL(iAccessKey,p) )
+ {
+ size = p->Length();
+ }
+ }
+ else
+ {
+ TDesC8 *p;
+ if ( iImpsData->RestoreDesc8L(iAccessKey,p) )
+ {
+ size = p->Length();
+ }
+ }
+
+ iAccessKey->PopL();
+ iAccessKey->AddL(EImpsKeyMessageInfo);
+ iAccessKey->AddL(EImpsKeyContentSize);
+ iImpsData->StoreIntegerL(iAccessKey,size);
+
+ NW_DOM_ElementNode_t *node = NULL;
+ TInt rcode = KErrNone;
+
+ if((node = NW_DOM_DocumentNode_createElementNodeByToken(iDocument,(TUint16)aToken)) != NULL)
+ {
+ rcode = EncodeValueL(aToken,node,0);
+
+ if(rcode == KErrNone)
+ {
+ // append node to parent node
+ NW_Status_t status = NW_DOM_Node_appendChild((NW_TinyTree_Node_s*)aNode,node);
+ if(status != NW_STAT_SUCCESS)
+ {
+ rcode = KImpsErrorEncode;
+ }
+ }
+
+ }
+ else
+ {
+ return(KImpsErrorEncode);
+ }
+
+ return(rcode);
+ }
+
+
+// ---------------------------------------------------------
+// CImpsEncodeWbXml::PopAccessKeyL
+// method updates data accessor key
+// ---------------------------------------------------------
+//
+void CImpsEncodeWbXml::PopAccessKeyL(TInt aToken)
+ {
+
+ if(iAccessKey->Count())
+ {
+ iAccessKey->PopL( );
+ switch(aToken)
+ {
+ case KImpsWbXmlTransactionContent:
+ iNameSpace = KImpsNameSpaceCspMessage;
+ break;
+
+ case KImpsWbXmlPresenceSubList:
+ iNameSpace = KImpsNameSpaceTransactionContent;
+ break;
+
+ default:
+ break;
+ }
+ }
+
+ }
+// ---------------------------------------------------------
+// CImpsEncodeWbXml::FetchNextElement
+// medhod fetches next child element if exists
+// ---------------------------------------------------------
+//
+TPtrC CImpsEncodeWbXml::FetchNextElement(SImpsValueList* aValueList,TInt& aElementCounter,
+ TInt& aRcode, TPtrC aElementList, TPtrC aCurrentElement)
+ {
+
+ TPtrC value;
+
+ if(aRcode == KErrNone)
+ {
+ if(aValueList->Flags & KImpsValueListMultiple ||
+ aValueList->Flags & KImpsValueListOnceOrMore)
+ {
+ value.Set(aCurrentElement);
+ aElementCounter++;
+ aRcode = KErrNone;
+ }
+ else
+ {
+ if(!(aValueList->Flags & KImpsValueListEnd) && !(aValueList->Flags & KImpsValueListAlternative))
+ {
+ value.Set(ReadNextValue(aValueList,aElementList));
+ aElementCounter = 0;
+ aRcode = KErrNone;
+ }
+ else
+ {
+ aRcode = KErrNotFound;
+ }
+ }
+ }
+ else
+ {
+ if(aRcode == KErrNotFound)
+ {
+ if(aValueList->Flags & KImpsValueListMultiple ||
+ aValueList->Flags & KImpsValueListOptional ||
+ aValueList->Flags & KImpsValueListAlternative)
+ {
+ if((aValueList->Flags & KImpsValueListAlternative) && aElementCounter)
+ {
+ aRcode = KErrNotFound;
+ }
+ else if(!(aValueList->Flags & KImpsValueListEnd))
+ {
+ value.Set(ReadNextValue(aValueList,aElementList));
+ aElementCounter = 0;
+ aRcode = KErrNone;
+ }
+ else
+ {
+ if(aValueList->Flags & KImpsValueListAlternative)
+ {
+ aRcode = KImpsErrorEncode;
+ }
+ else
+ {
+ aRcode = KErrNotFound;
+ }
+ }
+ }
+ else if(aValueList->Flags & KImpsValueListOnceOrMore && aElementCounter)
+ {
+ if(!(aValueList->Flags & KImpsValueListEnd))
+ {
+ if(!(aValueList->Flags & KImpsValueListEnd))
+ {
+ value.Set(ReadNextValue(aValueList,aElementList));
+ aElementCounter = 0;
+ aRcode = KErrNone;
+ }
+ else
+ {
+ aRcode = KErrNotFound;
+ }
+ }
+ }
+ else
+ {
+ aRcode = KImpsErrorEncode;
+ }
+ }
+ }
+
+ return value;
+
+ }
+// ---------------------------------------------------------
+// CImpsEncodeWbXml::SetDataAccessorKeyL
+// method updates data accessor key
+// ---------------------------------------------------------
+//
+TInt CImpsEncodeWbXml::SetDataAccessorKeyL(TInt aToken, TInt aIndex)
+ {
+
+ TInt impskey = KErrNotFound;
+ TInt primitive = KErrNotFound;
+
+ impskey = aToken;
+ switch(iNameSpace)
+ {
+
+ case KImpsNameSpaceCspMessage:
+
+ iKeyType = EImpsKeyTypeIM;
+// impskey = iWbXmlData->GetHeaderAccessKey(aToken);
+ iAccessKey->AddL(CREATEKEY(impskey,aIndex),iKeyType);
+ break;
+
+ case KImpsNameSpaceTransactionContent:
+ iKeyType = EImpsKeyTypeIM;
+// impskey = iWbXmlData->GetContentAccessKey(aToken);
+ iAccessKey->AddL(CREATEKEY(impskey,aIndex),iKeyType);
+ break;
+
+ case KImpsNameSpacePresenceSubList:
+ iKeyType = EImpsKeyTypePre;
+// impskey = iWbXmlData->GetPresenceAccessKey(aToken);
+ // impskey needs to be changed because
+ // the ContentType is in another namespace
+ if ( impskey == EImpsKeyContentType)
+ {
+ iKeyType = EImpsKeyTypeIM;
+ }
+ iAccessKey->AddL(CREATEKEY(impskey,aIndex),iKeyType);
+ break;
+
+ default:
+ break;
+
+ }
+
+ if(aToken == KImpsWbXmlTransactionContent)
+ {
+ iNameSpace = KImpsNameSpaceTransactionContent;
+
+ if(iPEC)
+ {
+ // pure data handle
+ primitive = iXmlUtils->XmlToTransactionContentL(*iImpsData);
+ }
+ }
+
+ if(aToken == KImpsWbXmlPresenceSubList)
+ {
+ iNameSpace = KImpsNameSpacePresenceSubList;
+ }
+
+ return(primitive);
+ }
+
+// ---------------------------------------------------------
+// CImpsEncodeWbXml::ReadElementList
+// method inits child element list
+// ---------------------------------------------------------
+//
+void CImpsEncodeWbXml::ReadElementList(TPtrC aElement, SImpsValueList* aElementList)
+ {
+
+ aElementList->Begin = aElement.Locate('(');
+ if(aElementList->Begin == KErrNotFound)
+ {
+ aElementList->Flags |= KImpsValueListEmpty;
+ }
+ else
+ {
+ aElementList->Length = aElement.Length() - aElementList->Begin;
+ aElementList->Flags = 0;
+ aElementList->Next = aElementList->Begin + 1;
+ }
+
+ }
+
+// ---------------------------------------------------------
+// CImpsEncodeWbXml::ReadToken
+// method reads WBXML token corresponding to element name
+// ---------------------------------------------------------
+//
+TInt CImpsEncodeWbXml::ReadToken(TPtrC aElement)
+ {
+
+ TInt length = aElement.Locate(' ')-1;
+ iElementValue->Des().Zero();
+ for(TInt i=0;i<length;i++)
+ {
+ iElementValue->Des().Append(aElement[i+1]);
+ }
+ iElementValue->Des().Append(NULL);
+
+ return(NW_WBXML_Dictionary_getTagToken(iDictionaries[iCurrentDictionary],(NW_String_UCS2Buff_t*)iElementValue->Ptr(),NW_TRUE));
+
+ }
+// ---------------------------------------------------------
+// CImpsEncodeWbXml::StoreInteger
+// method stores integer value
+// ---------------------------------------------------------
+//
+void CImpsEncodeWbXml::StoreInteger(TUint32 aValue, TPtr8 aBuffer)
+ {
+
+ TInt i = 0;
+ for(i=3;i>0;i--)
+ {
+ if((aValue >> (8*i)) & 0xff) break;
+ }
+ for(;i>0;i--)
+ {
+ aBuffer.Append((TUint8)(aValue >> (8*i)));
+ }
+
+ aBuffer.Append((TUint8)aValue);
+ }
+// ---------------------------------------------------------
+// CImpsEncodeWbXml::EncodeAttributes
+// method adds attribute values to (one) DOM node if exists
+// ---------------------------------------------------------
+//
+TInt CImpsEncodeWbXml::EncodeAttributes(TInt aToken, NW_DOM_ElementNode_t* aNode)
+ {
+
+ TUint value = iWbXmlData->GetWbXmlAttributeTokenValue(aToken, iCspVersion);
+ if(value)
+ {
+ TPtrC8 str = iWbXmlData->GetWbXmlAttributeStringValue(aToken, iCspVersion);
+ if(str.Length())
+ {
+ NW_String_initialize(&iString,(TUint8*)str.Ptr(),HTTP_utf_8);
+ if(NW_DOM_AttrVal_initFromString(&iAttribute,&iString) != NW_STAT_SUCCESS)
+ {
+
+ return KImpsErrorEncode;
+ }
+ }
+ if(NW_DOM_ElementNode_setAttributeByToken(aNode,(NW_Uint16)value,&iAttribute) != NW_STAT_SUCCESS)
+ {
+ return KImpsErrorEncode;
+ }
+ }
+ else
+ {
+ // ExtBlock handling is a special case
+ if (aToken == EImpsKeyExtBlock)
+ {
+ NW_String_initialize(&iString,(TUint8*)KAPIClientAttributeValue().Ptr(),HTTP_utf_8);
+ if(NW_DOM_AttrVal_initFromString(&iAttribute,&iString) != NW_STAT_SUCCESS)
+ {
+
+ return KImpsErrorEncode;
+ }
+
+ NW_String_initialize(&iString,(TUint8*)KAPIClientAttribute().Ptr(),HTTP_utf_8);
+ if (NW_DOM_ElementNode_setAttributeByAttrVal(aNode, &iString, &iAttribute )!= NW_STAT_SUCCESS)
+ {
+ return KImpsErrorEncode;
+ }
+ }
+ }
+
+ return(KErrNone);
+ }
+// ---------------------------------------------------------
+// CImpsEncodeWbXml::EncodeValueL
+// method reads element value from data accessor and stores
+// it to DOM tree
+// ---------------------------------------------------------
+//
+TInt CImpsEncodeWbXml::EncodeValueL(TInt aToken, NW_DOM_TextNode_t *aNode,TInt aIndex)
+ {
+ // this removes compiler warning
+ aIndex = KErrNone;
+ TInt rcode = aIndex;
+ TInt elemcount = 0;
+
+ switch(iImpsData->KeyTypeL(iAccessKey))
+ {
+ case EImpsDataTypeContentData:
+ {
+ if ( TImpsDataUtils::GetContentDataTypeL( iImpsData, 0 ) == EImpsDataTypeDesc8 )
+ {
+ rcode = EncodeString8L(aToken,elemcount);
+ }
+ else
+ {
+ rcode = EncodeStringL(aToken,elemcount);
+ }
+ }
+ break;
+ case EImpsDataTypeDesc8:
+ rcode = EncodeString8L(aToken,elemcount);
+ break;
+
+ case EImpsDataTypeDesc:
+ rcode = EncodeStringL(aToken,elemcount);
+ break;
+
+ case EImpsDataTypeInt:
+ rcode = EncodeIntegerL(aToken,elemcount);
+ break;
+
+ case EImpsDataTypeBoolean:
+ rcode = EncodeBooleanL(aToken,elemcount);
+ break;
+
+ case EImpsDataTypeExt:
+ rcode = EncodeExtL(aToken,elemcount);
+ break;
+
+ default:
+ rcode = KErrNotFound;
+ }
+
+ if(rcode == KErrNone)
+ {
+ for(TInt i=0;i<elemcount;i++)
+ {
+ NW_DOM_TextNode_t *node = NW_DOM_DocumentNode_createTextNodeWithTextItem(iDocument,&iTextItem[i]);
+ if(node)
+ {
+ if(NW_DOM_Node_appendChild((NW_TinyTree_Node_s*)aNode,node) != NW_STAT_SUCCESS)
+ {
+ rcode = KImpsErrorEncode;
+ break;
+ }
+ }
+ }
+ }
+ if(iStoreValue->Des().Length() > KImpsWbXmlMaxBufferSize)
+ {
+ delete iStoreValue;
+ iStoreValue = NULL;
+ iStoreValue = HBufC8::NewL(KImpsWbXmlMaxStringLength);
+ }
+
+ return(rcode);
+ }
+
+// ---------------------------------------------------------
+// CImpsEncodeWbXml::EncodeStringL
+// method stores string value to DOM node
+// ---------------------------------------------------------
+//
+TInt CImpsEncodeWbXml::EncodeStringL(TInt aToken,TInt& aElemCount)
+ {
+
+ NW_Status_t status = NW_STAT_SUCCESS;
+ TInt rcode = KErrNone;
+ TInt elem = 0;
+ TInt value = 0;
+ TInt maxlength = 0;
+
+ TDesC *p;
+ if(iImpsData->RestoreDescL(iAccessKey,p))
+ {
+ // presence data handling
+ if(iNameSpace == KImpsNameSpacePresenceSubList)
+ {
+ TInt token = iAccessKey->GetElementL((iAccessKey->Count() - 2),iKeyType);
+
+// // Lookup the value string in dictionary: NW_FALSE = no case sensitive
+// if((elem = NW_WBXML_Dictionary_getAttributeToken(
+// &NW_Imps_1_2_WBXMLDictionary, (NW_String_UCS2Buff_t*)p->Ptr(), 0, NW_FALSE)) != KErrNotFound)
+ if((elem = iWbXmlData->GetWbXmlElementValue(token,p)) != KImpsWbXmlDataNotFound)
+ {
+ status = NW_DOM_TextItem_initFromExtensionInt(&iTextItem[aElemCount++],NW_WBXML_EXT_T_0,elem);
+ if(status != NW_STAT_SUCCESS)
+ {
+ rcode = KImpsErrorEncode;
+ }
+ return rcode; // do not continue as we already added the string as extension
+ }
+ }
+
+// if((elem = NW_WBXML_Dictionary_getAttributeToken(
+// &NW_Imps_1_2_WBXMLDictionary, (NW_String_UCS2Buff_t*)p->Ptr(), 0, NW_FALSE)) != KErrNotFound)
+ if((elem = iWbXmlData->GetWbXmlElementValue(aToken,p)) != KImpsWbXmlDataNotFound)
+ {
+ status = NW_DOM_TextItem_initFromExtensionInt(&iTextItem[aElemCount++],NW_WBXML_EXT_T_0,elem);
+ if(status != NW_STAT_SUCCESS)
+ {
+ rcode = KImpsErrorEncode;
+ }
+ else
+ {
+ rcode = KErrNone;
+ }
+ return(rcode);
+ }
+ iWbXmlData->GetWbXmlElementValue(aToken,value,maxlength);
+ TPtr8 p8 = iStoreValue->Des();
+ TInt size = CountContentSize(p);
+ if(size >= p8.MaxLength())
+ {
+ delete iStoreValue;
+ iStoreValue = NULL;
+ iStoreValue = HBufC8::NewL(size+1);
+ p8.Set(iStoreValue->Des( ));
+ }
+ if(CnvUtfConverter::ConvertFromUnicodeToUtf8(p8,*p) == KErrNone)
+ {
+ // if its content data, only then escape XML which will convert
+ // special characters like & to &.
+ if (0x0D == aToken)
+ {
+ // Fix TSW Error Id: EDZG-7KXCAF
+ iStoreValue = iXmlUtils->EscapeXmlL(p8).AllocL();
+ iStoreValue = iStoreValue->ReAllocL(iStoreValue->Length() + 1 );
+ }
+
+ iStoreValue->Des().Append(0);
+ TInt offset = 0;
+ elem = SearchPrefix(iStoreValue->Des(),offset);
+ if(elem != KErrNotFound)
+ {
+ status = NW_DOM_TextItem_initFromExtensionInt(&iTextItem[aElemCount++],NW_WBXML_EXT_T_0,elem);
+ if(status != NW_STAT_SUCCESS)
+ {
+ return(KImpsErrorEncode);
+ }
+ }
+
+ NW_String_initialize(&iString,(TUint8*)iStoreValue->Des().Mid(offset).Ptr(),HTTP_utf_8);
+ status = NW_DOM_TextItem_initFromString(&iTextItem[aElemCount++],&iString);
+ if(status != NW_STAT_SUCCESS)
+ {
+ rcode = KImpsErrorEncode;
+ }
+ }
+ else
+ {
+ rcode = KImpsErrorEncode;
+ }
+ }
+ else
+ {
+ rcode = KErrNotFound;
+ }
+
+ return(rcode);
+}
+
+// ---------------------------------------------------------
+// CImpsEncodeWbXml::EncodeString8L
+// method stores 8 bit string value to DOM node
+// ---------------------------------------------------------
+//
+TInt CImpsEncodeWbXml::EncodeString8L(TInt aToken,TInt& aElemCount)
+ {
+
+ NW_Status_t status = NW_STAT_SUCCESS;
+ TInt rcode = KErrNone;
+ TInt elem = 0;
+ TInt value = 0;
+ TInt maxlength;
+
+ TDesC8 *p8;
+ if(iImpsData->RestoreDesc8L(iAccessKey,p8))
+ {
+ if((elem = iWbXmlData->GetWbXmlElementValue(aToken,value,maxlength))
+ != KImpsWbXmlDataNotFound)
+ {
+ StoreInteger(elem,iStoreValue->Des());
+ iString.storage = (TUint8*)iStoreValue->Ptr();
+ iString.length = iStoreValue->Length();
+ }
+ if(p8->Length() >= iStoreValue->Des().MaxLength())
+ {
+ delete iStoreValue;
+ iStoreValue = NULL;
+ iStoreValue = HBufC8::NewL(p8->Length() + 1);
+ }
+ iStoreValue->Des().Copy(*p8);
+/*
+ if(aToken == KImpsWbXmlDirectContent || aToken == KImpsWbXmlContainedvCard)
+ {
+ iOpaque.data = (TUint8*)iStoreValue->Ptr();
+ iOpaque.length = iStoreValue->Length();
+ status = NW_DOM_TextItem_initFromOpaque(&iTextItem[aElemCount++],iOpaque.length,iOpaque.data);
+ if(status != NW_STAT_SUCCESS)
+ {
+ rcode = KImpsErrorEncode;
+ }
+ }
+ else
+*/
+ {
+ iStoreValue->Des().Append(0);
+ NW_String_initialize(&iString,(TUint8*)iStoreValue->Des().Ptr(),HTTP_utf_8);
+ status = NW_DOM_TextItem_initFromString(&iTextItem[aElemCount++],&iString);
+ if(status != NW_STAT_SUCCESS)
+ {
+ rcode = KImpsErrorEncode;
+ }
+ }
+
+ }
+ else
+ {
+ rcode = KErrNotFound;
+ }
+
+ return(rcode);
+
+ }
+
+// ---------------------------------------------------------
+// CImpsEncodeWbXml::EncodeExt
+// method stores extension value to DOM node
+// ---------------------------------------------------------
+//
+TInt CImpsEncodeWbXml::EncodeExtL(TInt aToken,TInt& aElemCount)
+ {
+
+ NW_Status_t status = NW_STAT_SUCCESS;
+ TInt rcode = KErrNone;
+ TInt elem = 0;
+ TInt value = 0;
+ TInt maxlength;
+
+ TDesC8 *p8;
+ if(iImpsData->RestoreDesc8L(iAccessKey,p8))
+ {
+ if((elem = iWbXmlData->GetWbXmlElementValue(aToken,value,maxlength))
+ != KImpsWbXmlDataNotFound)
+ {
+ StoreInteger(elem,iStoreValue->Des());
+ iString.storage = (TUint8*)iStoreValue->Ptr();
+ iString.length = iStoreValue->Length();
+ }
+ if(maxlength && p8->Length() > maxlength)
+ {
+ rcode = KImpsErrorEncode;
+ }
+ else
+ {
+ if(p8->Length() >= iStoreValue->Des().MaxLength())
+ {
+ delete iStoreValue;
+ iStoreValue = NULL;
+ iStoreValue = HBufC8::NewL(p8->Length() + 1);
+ }
+ iStoreValue->Des().Copy(*p8);
+ iStoreValue->Des().Append(0);
+ NW_String_initialize(&iString,(TUint8*)iStoreValue->Des().Ptr(),HTTP_utf_8);
+ status = NW_DOM_TextItem_initFromString(&iTextItem[aElemCount++],&iString);
+ if(status != NW_STAT_SUCCESS)
+ {
+ rcode = KImpsErrorEncode;
+ }
+ }
+ }
+ else
+ {
+ rcode = KErrNotFound;
+ }
+
+ return(rcode);
+ }
+
+// ---------------------------------------------------------
+// CImpsEncodeWbXml::EncodeIntegerL
+// method stores integer value to DOM node
+// ---------------------------------------------------------
+//
+TInt CImpsEncodeWbXml::EncodeIntegerL(TInt aToken,TInt& aElemCount)
+ {
+
+ NW_Status_t status = NW_STAT_SUCCESS;
+ TInt rcode = KErrNone;
+ TInt elem;
+ TInt value;
+ TInt maxlength;
+
+ if(iImpsData->RestoreIntegerL(iAccessKey,value))
+ {
+ elem = iWbXmlData->GetWbXmlElementValue(aToken,value,maxlength);
+ if(elem == KImpsWbXmlDataNotFound)
+ {
+ TPtrC8 p = iWbXmlData->GetWbXmlStringValue(aToken,value);
+ if(p.Length())
+ {
+ NW_String_initialize(&iString,(TUint8*)p.Ptr(),HTTP_utf_8);
+ status = NW_DOM_TextItem_initFromString(&iTextItem[aElemCount++],&iString);
+ if(status != NW_STAT_SUCCESS)
+ {
+ rcode = KImpsErrorEncode;
+ }
+ }
+ else
+ {
+ iStoreValue->Des().Zero();
+ StoreInteger(value,iStoreValue->Des());
+ iOpaque.data = (TUint8*)iStoreValue->Ptr();
+ iOpaque.length = iStoreValue->Length();
+ status = NW_DOM_TextItem_initFromOpaque(&iTextItem[aElemCount++],iOpaque.length,iOpaque.data);
+ if(status != NW_STAT_SUCCESS)
+ {
+ rcode = KImpsErrorEncode;
+ }
+ }
+ }
+ else
+ {
+ status = NW_DOM_TextItem_initFromExtensionInt(&iTextItem[aElemCount++],NW_WBXML_EXT_T_0,elem);
+ if(status != NW_STAT_SUCCESS)
+ {
+ rcode = KImpsErrorEncode;
+ }
+ }
+ }
+ else
+ {
+ rcode = KErrNotFound;
+ }
+
+ return(rcode);
+ }
+
+// ---------------------------------------------------------
+// CImpsEncodeWbXml::SearchPrefix
+// method searches prefixes from given string
+// ---------------------------------------------------------
+//
+TInt CImpsEncodeWbXml::SearchPrefix(TPtrC8 aString,TInt& aOffset)
+ {
+
+ TPtrC8 ptr(KImpsHttps8);
+ if(aString.Find(ptr) == 0)
+ {
+ aOffset = ptr.Length();
+ return(KImpsWbXmlHttps);
+ }
+
+ ptr.Set(KImpsHttp8);
+ if(aString.Find(ptr) == 0)
+ {
+ aOffset = ptr.Length();
+ return(KImpsWbXmlHttp);
+ }
+
+ return(KErrNotFound);
+
+ }
+
+// ---------------------------------------------------------
+// CImpsEncodeWbXml::EncodeBooleanL
+// method stores boolean value to DOM node
+// ---------------------------------------------------------
+//
+TInt CImpsEncodeWbXml::EncodeBooleanL(TInt aToken,TInt& aElemCount)
+ {
+
+ NW_Status_t status = NW_STAT_SUCCESS;
+ TInt elem;
+ TInt value;
+ TInt maxlength;
+ TInt rcode = KErrNone;
+
+ if(iImpsData->RestoreBooleanL(iAccessKey,value))
+ {
+ elem = iWbXmlData->GetWbXmlElementValue(aToken,value,maxlength);
+ if(elem == KImpsWbXmlDataNotFound)
+ {
+ rcode = KErrNotFound;
+ }
+ else
+ {
+ status = NW_DOM_TextItem_initFromExtensionInt(&iTextItem[aElemCount++],NW_WBXML_EXT_T_0,elem);
+ if(status != NW_STAT_SUCCESS)
+ {
+ rcode = KImpsErrorEncode;
+ }
+ }
+ }
+ else
+ {
+ rcode = KErrNotFound;
+ }
+
+ return(rcode);
+ }
+
+// ---------------------------------------------------------
+// CImpsEncodeWbXml::ReadNextValue
+// method reads next value in element declaration
+// ---------------------------------------------------------
+//
+TPtrC CImpsEncodeWbXml::ReadNextValue(SImpsValueList* aValueList,TPtrC aValues)
+ {
+
+ aValueList->Flags &= KImpsValueListAlternative;
+ TBool end = EFalse;
+
+ while(aValues[aValueList->Next] == KImpsSpace) aValueList->Next++;
+ aValueList->Current = aValueList->Next;
+
+ TInt length = 0;
+ while(aValues[aValueList->Next] != ',' &&
+ aValues[aValueList->Next] != ')' &&
+ aValues[aValueList->Next] != '|')
+ {
+
+ if(aValues[aValueList->Next] == '?')
+ {
+ aValueList->Flags |= KImpsValueListOptional;
+ end = ETrue;
+ }
+
+ if(aValues[aValueList->Next] == '+')
+ {
+ aValueList->Flags |= KImpsValueListOnceOrMore;
+ end = ETrue;
+ }
+ if(aValues[aValueList->Next] == '*')
+ {
+ aValueList->Flags |= KImpsValueListMultiple;
+ end = ETrue;
+ }
+ if(aValues[aValueList->Next] == KImpsSpace)
+ {
+ end = ETrue;
+ }
+ aValueList->Next++;
+ if(end == EFalse) length++;
+ }
+
+ if(aValues[aValueList->Next] == '|')
+ {
+ aValueList->Flags |= KImpsValueListAlternative;
+ }
+
+ if(aValues[aValueList->Next] == ')')
+ {
+ aValueList->Flags |= KImpsValueListEnd;
+ }
+ aValueList->Next++;
+
+ return(aValues.Mid(aValueList->Current,length));
+ }
+
+// ---------------------------------------------------------
+// CImpsEncodeWbXml::MimeType
+// method returns wbxml message MIME type
+// ---------------------------------------------------------
+//
+TPtrC8 CImpsEncodeWbXml::MimeType( )
+ {
+
+ return TPtrC8(KImpsWbXmlMessageMimeType);
+
+ }
+
+// ---------------------------------------------------------
+// CImpsEncodeWbXml::CountContentSize
+// method count string size
+// ---------------------------------------------------------
+//
+TInt CImpsEncodeWbXml::CountContentSize(TDesC*& aPtr)
+ {
+
+ TInt size = 0;
+ for (TInt j = 0; j < aPtr->Length(); j++)
+ {
+ TChar byte = TChar(aPtr->Ptr()[j]);
+ if ( byte < 0x0080)
+ size += 0;
+ else if ( byte < 0x0800)
+ size += 1;
+ else if ( byte < 0x10000)
+ size += 2;
+ else if ( byte < 0x20000)
+ size += 3;
+ else if ( byte < 0x4000000)
+ size += 4;
+ else
+ size += 5;
+ }
+ size += aPtr->Length();
+ return(size);
+ }
+
+//
+// ---------------------------------------------------------
+// NewEncoderL()
+// wbxml encoder create function
+// Returns: C-class entity of abstract MImpsEncoder class
+// ---------------------------------------------------------
+//
+
+EXPORT_C GLDEF_C MImpsEncoder* NewEncoderL( )
+ {
+
+ return (MImpsEncoder*) CImpsEncodeWbXml::NewL( );
+
+ }
+
+// ---------------------------------------------------------
+// CImpsEncodeWbXml::Destroy
+// message encoder destructor
+// ---------------------------------------------------------
+//
+void CImpsEncodeWbXml::Destroy( )
+ {
+
+ delete this;
+
+ }
+
+// End of File
+