IMPSengine/messageencoder/wbxml/src/ImpsEncodeWbXml.cpp
changeset 0 094583676ce7
--- /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 &amp;.
+			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  
+