webengine/widgetregistry/Server/src/WidgetRegistryXml.cpp
changeset 0 dd21522fd290
child 17 c8a366e56285
equal deleted inserted replaced
-1:000000000000 0:dd21522fd290
       
     1 /*
       
     2 * Copyright (c) 2008 Nokia Corporation and/or its subsidiary(-ies).
       
     3 * All rights reserved.
       
     4 * This component and the accompanying materials are made available
       
     5 * under the terms of the License "Eclipse Public License v1.0"
       
     6 * which accompanies this distribution, and is available
       
     7 * at the URL "http://www.eclipse.org/legal/epl-v10.html".
       
     8 *
       
     9 * Initial Contributors:
       
    10 * Nokia Corporation - initial contribution.
       
    11 *
       
    12 * Contributors:
       
    13 *
       
    14 * Description:  Processes registry persistent data in XML.
       
    15 *
       
    16 */
       
    17 
       
    18 
       
    19 #include <e32base.h>
       
    20 #include <f32file.h>
       
    21 #include <libxml2_globals.h>
       
    22 #include <libxml2_parser.h>
       
    23 #include <charconv.h>
       
    24 #include "WidgetRegistryXml.h"
       
    25 
       
    26 _LIT( KPropertyListVersion,  "PropertyListVersion" );
       
    27 _LIT( KBundleIdentifier,     "BundleIdentifier" );
       
    28 _LIT( KBundleName,           "BundleName" );
       
    29 _LIT( KBundleDisplayName,    "BundleDisplayName" );
       
    30 _LIT( KMainHTML,             "MainHTML" );
       
    31 _LIT( KBundleShortVersion,   "BundleShortVersion" );
       
    32 _LIT( KBundleVersion,        "BundleVersion" );
       
    33 _LIT( KHeight,               "Height" );
       
    34 _LIT( KWidth,                "Width" );
       
    35 _LIT( KAllowFullAccess,      "AllowFullAccess" );
       
    36 _LIT( KAllowNetworkAccess,   "AllowNetworkAccess" );
       
    37 _LIT( KDriveName,            "DriveName" );
       
    38 _LIT( KBasePath,             "BasePath" );
       
    39 _LIT( KIconPath,             "IconPath" );
       
    40 _LIT( KUrl,                  "Url" );
       
    41 _LIT( KFileSize,             "FileSize" );
       
    42 _LIT( KUid,                  "Uid" );
       
    43 _LIT( KNokiaWidget,          "NokiaWidget" );
       
    44 _LIT( KMiniViewEnabled,      "MiniViewEnabled" );
       
    45 _LIT( KBlanketPermGranted,   "BlanketPermissionGranted" );         // optional
       
    46 
       
    47 static void XmlFree( TAny* aPtr )
       
    48     {
       
    49     __ASSERT_DEBUG( aPtr, User::Invariant() );
       
    50     xmlChar* ptr( (xmlChar*)(aPtr ) );
       
    51     xmlFree( ptr );
       
    52     }
       
    53 // ============================================================================
       
    54 // CWidgetRegistryXml::NewL()
       
    55 // two-phase constructor
       
    56 //
       
    57 // @since 5.0
       
    58 // ============================================================================
       
    59 //
       
    60 CWidgetRegistryXml* CWidgetRegistryXml::NewL()
       
    61     {
       
    62     CWidgetRegistryXml *self = new (ELeave) CWidgetRegistryXml();
       
    63     CleanupStack::PushL( self );
       
    64     self->ConstructL();
       
    65     CleanupStack::Pop();
       
    66     return self;
       
    67     }
       
    68 
       
    69 // ============================================================================
       
    70 // CWidgetRegistryXml::CWidgetRegistryXml()
       
    71 // C++ constructor
       
    72 //
       
    73 // @since 5.0
       
    74 // ============================================================================
       
    75 //
       
    76 CWidgetRegistryXml::CWidgetRegistryXml() : iProperties(EWidgetPropertyIdCount)
       
    77     {
       
    78     }
       
    79 
       
    80 // ============================================================================
       
    81 // CWidgetUIConfigHandler::ConstructL()
       
    82 // C++ constructor
       
    83 //
       
    84 // @since 5.0
       
    85 // ============================================================================
       
    86 //
       
    87 void CWidgetRegistryXml::ConstructL()
       
    88     {
       
    89     TWidgetProperty property;
       
    90 
       
    91     property.id = EWidgetPropertyListVersion;
       
    92     property.name.Set( KPropertyListVersion );
       
    93     property.type = EWidgetPropTypeInt;
       
    94     iProperties.AppendL(property);
       
    95     //
       
    96     property.id = EBundleIdentifier;
       
    97     property.name.Set( KBundleIdentifier );
       
    98     property.type = EWidgetPropTypeString;
       
    99     iProperties.AppendL(property);
       
   100     //
       
   101     property.id = EBundleName;
       
   102     property.name.Set( KBundleName );
       
   103     property.type = EWidgetPropTypeString;
       
   104     iProperties.AppendL(property);
       
   105     //
       
   106     property.id = EBundleDisplayName;
       
   107     property.name.Set( KBundleDisplayName );
       
   108     property.type = EWidgetPropTypeString;
       
   109     iProperties.AppendL(property);
       
   110     //
       
   111     property.id = EMainHTML;
       
   112     property.name.Set( KMainHTML );
       
   113     property.type = EWidgetPropTypeString;
       
   114     iProperties.AppendL(property);
       
   115     //
       
   116     property.id = EBundleShortVersion;
       
   117     property.name.Set( KBundleShortVersion );
       
   118     property.type = EWidgetPropTypeString;
       
   119     iProperties.AppendL(property);
       
   120     //
       
   121     property.id = EBundleVersion;
       
   122     property.name.Set( KBundleVersion );
       
   123     property.type = EWidgetPropTypeString;
       
   124     iProperties.AppendL(property);
       
   125     //
       
   126     property.id = EHeight;
       
   127     property.name.Set( KHeight );
       
   128     property.type = EWidgetPropTypeInt;
       
   129     iProperties.AppendL(property);
       
   130     //
       
   131     property.id = EWidth;
       
   132     property.name.Set( KWidth );
       
   133     property.type = EWidgetPropTypeInt;
       
   134     iProperties.AppendL(property);
       
   135     //
       
   136     property.id = EAllowFullAccess;
       
   137     property.name.Set( KAllowFullAccess );
       
   138     property.type = EWidgetPropTypeInt;
       
   139     iProperties.AppendL(property);
       
   140     //
       
   141     property.id = EAllowNetworkAccess;
       
   142     property.name.Set( KAllowNetworkAccess );
       
   143     property.type = EWidgetPropTypeInt;
       
   144     iProperties.AppendL(property);
       
   145     //
       
   146     property.id = EDriveName;
       
   147     property.name.Set( KDriveName );
       
   148     property.type = EWidgetPropTypeString;
       
   149     iProperties.AppendL(property);
       
   150     //
       
   151     property.id = EBasePath;
       
   152     property.name.Set( KBasePath );
       
   153     property.type = EWidgetPropTypeString;
       
   154     iProperties.AppendL(property);
       
   155     //
       
   156     property.id = EIconPath;
       
   157     property.name.Set( KIconPath );
       
   158     property.type = EWidgetPropTypeString;
       
   159     iProperties.AppendL(property);
       
   160     //
       
   161     property.id = EUrl;
       
   162     property.name.Set( KUrl );
       
   163     property.type = EWidgetPropTypeString;
       
   164     iProperties.AppendL(property);
       
   165     //
       
   166     property.id = EFileSize;
       
   167     property.name.Set( KFileSize );
       
   168     property.type = EWidgetPropTypeInt;
       
   169     iProperties.AppendL(property);
       
   170     //
       
   171     property.id = EUid;
       
   172     property.name.Set( KUid );
       
   173     property.type = EWidgetPropTypeInt; // not TUid
       
   174     iProperties.AppendL(property);
       
   175     //
       
   176     property.id = ENokiaWidget;
       
   177     property.name.Set( KNokiaWidget );
       
   178     property.type = EWidgetPropTypeInt;
       
   179     iProperties.AppendL(property);
       
   180     //
       
   181     property.id = EMiniViewEnable;
       
   182     property.name.Set( KMiniViewEnabled );
       
   183     property.type = EWidgetPropTypeInt;
       
   184     iProperties.AppendL(property);
       
   185     //
       
   186     property.id = EBlanketPermGranted;
       
   187     property.name.Set( KBlanketPermGranted );
       
   188     property.type = EWidgetPropTypeInt;
       
   189     iProperties.AppendL(property);
       
   190     }
       
   191 
       
   192 // ============================================================================
       
   193 // CWidgetRegistryXml::~CWidgetRegistryXml()
       
   194 // destructor
       
   195 //
       
   196 // @since 5.0
       
   197 // ============================================================================
       
   198 //
       
   199 CWidgetRegistryXml::~CWidgetRegistryXml()
       
   200     {
       
   201     for (TInt i = iProperties.Count() - 1; i >= EWidgetPropertyIdCount; i--)
       
   202         {
       
   203         TUint16* name = const_cast<TUint16*>(iProperties[i].name.Ptr());
       
   204         iProperties[i].name.Set(KNullDesC);
       
   205         delete [] name;
       
   206         }
       
   207     iProperties.Reset();
       
   208     iProperties.Close();
       
   209     }
       
   210 
       
   211 // ============================================================================
       
   212 // Get the property descriptiont by finding entry for name.
       
   213 //
       
   214 // @param aPropName The name of the prop: <prop>propName</prop>
       
   215 // @since 5.0
       
   216 // @return prop type.
       
   217 // ============================================================================
       
   218 //
       
   219 TInt CWidgetRegistryXml::GetPropertyId(
       
   220     const TDesC& aPropName )
       
   221     {
       
   222     TInt i = 0;
       
   223     for (; i < iProperties.Count(); ++i )
       
   224         {
       
   225         // use case insensitive match for property names
       
   226         if ( 0 == aPropName.CompareF( iProperties[i].name ) )
       
   227             {
       
   228             return iProperties[i].id;
       
   229             }
       
   230         }
       
   231     TUint16* name = NULL;
       
   232     name = new TUint16 [aPropName.Length()];
       
   233     if (name)
       
   234         {
       
   235         TPtr namePtr(name, aPropName.Length());
       
   236         namePtr.Copy(aPropName);
       
   237         TWidgetProperty property;
       
   238         property.id = iProperties.Count();
       
   239         property.name.Set( namePtr );
       
   240         property.type = EWidgetPropTypeUnknown;
       
   241         TInt err = iProperties.Append(property);
       
   242         if (err == KErrNone)
       
   243             {
       
   244             return iProperties.Count() - 1;
       
   245             }
       
   246         delete name;
       
   247         }
       
   248     return EWidgetPropertyIdInvalid;
       
   249     }
       
   250 
       
   251 // ============================================================================
       
   252 // Get the property name from the property id. Used in entry Externalize
       
   253 //
       
   254 // @param aPropertyId property id
       
   255 // @since 5.0
       
   256 // @return property name.
       
   257 // ============================================================================
       
   258 //
       
   259 
       
   260 const TPtrC& CWidgetRegistryXml::XmlPropertyName(
       
   261     TInt aPropertyId )
       
   262     {
       
   263     for ( TInt i = 0; i < iProperties.Count(); i++ )
       
   264         {
       
   265         if ( iProperties[i].id == aPropertyId )
       
   266             {
       
   267             return iProperties[i].name;
       
   268             }
       
   269         }
       
   270     return iProperties[0].name; // should never get here
       
   271     }
       
   272 
       
   273 
       
   274 // ============================================================================
       
   275 // CWidgetRegistryXml::ToUnicodeL
       
   276 // Utility to bundle transcoding to unicode steps.
       
   277 //
       
   278 // @since 5.0
       
   279 // @param aEncoding input buffer encoding
       
   280 // @param aUnicodeSizeMultiplier how many bytes of input make one unicode char
       
   281 // @param aInBuf input data in encoding
       
   282 // @param aOutBuf malloc'ed output buf, caller takes ownership
       
   283 // @param aFileSession CCnvCharacterSetConverter requires it
       
   284 // ============================================================================
       
   285 //
       
   286 void CWidgetRegistryXml::ToUnicodeL( TInt aEncoding,
       
   287                                      TInt aUnicodeSizeMultiplier,
       
   288                                      TPtrC8 aInBuf, HBufC16** aOutBuf,
       
   289                                      RFs& aFileSession )
       
   290     {
       
   291     *aOutBuf = NULL;
       
   292 
       
   293     // outbuf sizing and alloction
       
   294     HBufC16* outBuf = HBufC16::NewLC(aUnicodeSizeMultiplier * aInBuf.Length());
       
   295     TPtr16 outPtr = outBuf->Des();
       
   296 
       
   297     // convert to unicode
       
   298     CCnvCharacterSetConverter* charConv = CCnvCharacterSetConverter::NewLC();
       
   299     charConv->PrepareToConvertToOrFromL( aEncoding, aFileSession );
       
   300     TInt state = CCnvCharacterSetConverter::KStateDefault;
       
   301     TInt rep = 0; // number of unconvertible characters
       
   302     TInt rIndx = 0; // index of first unconvertible character
       
   303     User::LeaveIfError(
       
   304         charConv->ConvertToUnicode( outPtr, aInBuf, state, rep, rIndx ) );
       
   305     CleanupStack::PopAndDestroy( charConv );
       
   306 
       
   307     CleanupStack::Pop( outBuf );
       
   308     *aOutBuf = outBuf;
       
   309     }
       
   310 
       
   311 // ============================================================================
       
   312 // CWidgetRegistryXml::FromUnicodeL
       
   313 // Utility to bundle transcoding to unicode steps.
       
   314 //
       
   315 // @since 5.0
       
   316 // @param aEncoding input buffer encoding
       
   317 // @param aUnicodeSizeMultiplier how many bytes of input make one unicode char
       
   318 // @param aInBuf input data in encoding
       
   319 // @param aOutBuf malloc'ed output buf, caller takes ownership
       
   320 // @param aFileSession CCnvCharacterSetConverter requires it
       
   321 // ============================================================================
       
   322 //
       
   323 void CWidgetRegistryXml::FromUnicodeL( TInt aEncoding,
       
   324                                      TInt aUnicodeSizeMultiplier,
       
   325                                      TPtrC16 aInBuf, HBufC8** aOutBuf,
       
   326                                      RFs& aFileSession )
       
   327     {
       
   328     *aOutBuf = NULL;
       
   329 
       
   330     // outbuf sizing and alloction
       
   331     HBufC8* outBuf = HBufC8::NewLC(aUnicodeSizeMultiplier * (aInBuf.Length() + 1));
       
   332     TPtr8 outPtr = outBuf->Des();
       
   333 
       
   334     // convert from unicode
       
   335     CCnvCharacterSetConverter* charConv = CCnvCharacterSetConverter::NewLC();
       
   336     charConv->PrepareToConvertToOrFromL( aEncoding, aFileSession );
       
   337     User::LeaveIfError(
       
   338         charConv->ConvertFromUnicode( outPtr, aInBuf));
       
   339     outPtr.ZeroTerminate();
       
   340     CleanupStack::PopAndDestroy( charConv );
       
   341 
       
   342     CleanupStack::Pop( outBuf ); 
       
   343     *aOutBuf = outBuf;
       
   344     }
       
   345 
       
   346 // ============================================================================
       
   347 // CWidgetRegistryXml::GetContentL
       
   348 // Utility to bundle extraction of XML text content
       
   349 //
       
   350 // @since 5.0
       
   351 // @param aEncoding input buffer encoding
       
   352 // @param aUnicodeSizeMultiplier how many bytes of input make one unicode char
       
   353 // @param aInBuf input data in encoding
       
   354 // @param aOutBuf malloc'ed output buf, caller takes ownership
       
   355 // @param aFileSession CCnvCharacterSetConverter requires it
       
   356 // ============================================================================
       
   357 //
       
   358 void CWidgetRegistryXml::GetContentL( RFs& aFileSession,
       
   359                                       xmlDocPtr aDoc,
       
   360                                       xmlNode* aNode,
       
   361                                       HBufC** aContent )
       
   362     {
       
   363     // xml uses UTF-8 for the internal representation
       
   364     xmlChar* xmlContent =
       
   365         xmlNodeListGetString( aDoc, aNode, 1 /* expand entities inline */);
       
   366     if ( NULL == xmlContent )
       
   367         {
       
   368         User::Leave( OOM_FLAG ? KErrNoMemory : KErrCorrupt );
       
   369         }
       
   370     // we must transcode UTF-8 to UCS-2 (historical
       
   371     // and now inaccurate name "unicode")
       
   372     TCleanupItem item( XmlFree, xmlContent );
       
   373     CleanupStack::PushL( item );
       
   374     TPtrC8 content( xmlContent );
       
   375     ToUnicodeL( KCharacterSetIdentifierUtf8, 2,
       
   376                 content, aContent, aFileSession );
       
   377     CleanupStack::PopAndDestroy(); // xmlContent equivalent to xmlFree()
       
   378     if ( NULL == *aContent )
       
   379         {
       
   380         User::Leave( KErrCorrupt );
       
   381         }
       
   382     }
       
   383 
       
   384 // ============================================================================
       
   385 // CWidgetRegistryXml::GetTextContentAsStringL
       
   386 //
       
   387 // ============================================================================
       
   388 //
       
   389 void CWidgetRegistryXml::GetTextContentAsStringL( RFs& aFileSession, xmlDocPtr aDoc,
       
   390                                                   xmlNode* aNode, HBufC** aContent )
       
   391     {
       
   392     HBufC* tmpBuf = NULL;
       
   393     TInt len = 0;
       
   394     GetSubtreeAsStringL (aFileSession, aDoc, aNode, NULL, len);
       
   395     tmpBuf = HBufC::NewLC(len);
       
   396     GetSubtreeAsStringL (aFileSession, aDoc, aNode, &tmpBuf, len);
       
   397     *aContent = tmpBuf;
       
   398     CleanupStack::Pop(); // tmpBuf
       
   399     }
       
   400 
       
   401 void  CWidgetRegistryXml::GetSubtreeAsStringL (RFs& aFileSession, xmlDocPtr aDoc, xmlNode* aNode, HBufC** aBuf, TInt& aLen)
       
   402     {
       
   403     xmlNode* node = aNode;
       
   404     switch (node->type)
       
   405         {
       
   406         case XML_ELEMENT_NODE:
       
   407             {
       
   408             const xmlChar* name = node->name;
       
   409             TPtrC8 tmpName(name);
       
   410             if (aBuf)
       
   411                 {
       
   412                 HBufC* tmpBuf = NULL;
       
   413                 ToUnicodeL( KCharacterSetIdentifierUtf8, 2,
       
   414                             tmpName, &tmpBuf, aFileSession );
       
   415                 CleanupStack::PushL(tmpBuf);
       
   416                 (*aBuf)->Des().Append(_L("<"));
       
   417                 (*aBuf)->Des().Append(*tmpBuf);
       
   418                 (*aBuf)->Des().Append(_L(">"));
       
   419                 if (node->children)
       
   420                     {
       
   421                     GetSubtreeAsStringL (aFileSession, aDoc, node->children, aBuf, aLen);
       
   422                     }
       
   423                 (*aBuf)->Des().Append(_L("</"));
       
   424                 (*aBuf)->Des().Append(*tmpBuf);
       
   425                 (*aBuf)->Des().Append(_L(">"));
       
   426                 CleanupStack::PopAndDestroy(tmpBuf);
       
   427                 }
       
   428             else
       
   429                 {
       
   430                 aLen += (5 + 2 * tmpName.Length());
       
   431                 if (node->children)
       
   432                     {
       
   433                     GetSubtreeAsStringL (aFileSession, aDoc, node->children, aBuf, aLen);
       
   434                     }
       
   435                 }
       
   436             break;
       
   437             }
       
   438         //case XML_ATTRIBUTE_NODE:
       
   439         case XML_TEXT_NODE:
       
   440             {
       
   441             xmlChar* content = node->content;
       
   442             TPtrC8 tmpContent(content);
       
   443             if (aBuf)
       
   444                 {
       
   445                 HBufC* tmpBuf = NULL;
       
   446                 xmlChar* encodedContent = EncodeStringL(aDoc, content);
       
   447                 TCleanupItem item( XmlFree, encodedContent );
       
   448                 CleanupStack::PushL(item);
       
   449                 TPtrC8 encodedContentPtr(encodedContent);
       
   450                 ToUnicodeL( KCharacterSetIdentifierUtf8, 2,
       
   451                             encodedContentPtr, &tmpBuf, aFileSession );
       
   452                 CleanupStack::PushL(tmpBuf);
       
   453                 (*aBuf)->Des().Append(*tmpBuf);
       
   454                 CleanupStack::PopAndDestroy(2); // encodedContent, tmpBuf
       
   455                 }
       
   456             else
       
   457                 {
       
   458                 aLen += EncodedStringLength(tmpContent);
       
   459                 }
       
   460             break;
       
   461             }
       
   462         case XML_CDATA_SECTION_NODE:
       
   463             {
       
   464             xmlChar* content = node->content;
       
   465             TPtrC8 tmpContent(content);
       
   466             if (aBuf)
       
   467                 {
       
   468                 HBufC* tmpBuf = NULL;
       
   469                 ToUnicodeL( KCharacterSetIdentifierUtf8, 2,
       
   470                             content, &tmpBuf, aFileSession);
       
   471                 CleanupStack::PushL(tmpBuf);
       
   472                 (*aBuf)->Des().Append(_L("<![CDATA["));
       
   473                 (*aBuf)->Des().Append(*tmpBuf);
       
   474                 (*aBuf)->Des().Append(_L("]]>"));
       
   475                 CleanupStack::PopAndDestroy(); // tmpBuf
       
   476                 }
       
   477             else
       
   478                 {
       
   479                 aLen += (12 + tmpContent.Length());
       
   480                 }
       
   481             break;
       
   482             }
       
   483         //case XML_ENTITY_REF_NODE:
       
   484         //case XML_ENTITY_NODE:
       
   485         //case XML_PI_NODE:
       
   486         //case XML_COMMENT_NODE:
       
   487         //case XML_DOCUMENT_NODE:
       
   488         //case XML_DOCUMENT_TYPE_NODE:
       
   489         //case XML_DOCUMENT_FRAG_NODE:
       
   490         //case XML_NOTATION_NODE:
       
   491         //case XML_HTML_DOCUMENT_NODE:
       
   492         //case XML_DTD_NODE:
       
   493         //case XML_ELEMENT_DECL:
       
   494         //case XML_ATTRIBUTE_DECL:
       
   495         //case XML_ENTITY_DECL:
       
   496         //case XML_NAMESPACE_DECL:
       
   497         //case XML_XINCLUDE_START:
       
   498         //case XML_XINCLUDE_END:
       
   499         }
       
   500     if (node->next)
       
   501         {
       
   502         node = node->next;
       
   503         GetSubtreeAsStringL(aFileSession, aDoc, node, aBuf, aLen);
       
   504         }
       
   505     }
       
   506 
       
   507 xmlChar* CWidgetRegistryXml::EncodeStringL(xmlDocPtr aDoc, xmlChar* aStringToConvert)
       
   508     {
       
   509     xmlChar* noEntitiesContent = xmlEncodeSpecialChars(aDoc, aStringToConvert);
       
   510     if ( NULL == noEntitiesContent )
       
   511         {
       
   512         User::Leave( OOM_FLAG ? KErrNoMemory : KErrCorrupt );
       
   513         }
       
   514     return noEntitiesContent;
       
   515     }
       
   516 
       
   517 HBufC* CWidgetRegistryXml::EncodeStringL(xmlDocPtr aDoc, TPtrC aStringToConvert, RFs& aFileSession)
       
   518     {
       
   519     HBufC8* out = NULL;
       
   520     FromUnicodeL( KCharacterSetIdentifierUtf8, 2, aStringToConvert, &out, aFileSession );
       
   521     CleanupStack::PushL(out);
       
   522     xmlChar* noEntitiesContent = xmlEncodeSpecialChars(aDoc, out->Des().Ptr());
       
   523     if ( NULL == noEntitiesContent )
       
   524         {
       
   525         User::Leave( OOM_FLAG ? KErrNoMemory : KErrCorrupt );
       
   526         }
       
   527     TCleanupItem item( XmlFree, noEntitiesContent );
       
   528     CleanupStack::PushL(item);
       
   529     TPtrC8 noEntitiesPtr(noEntitiesContent);
       
   530     HBufC* noEntitiesBuf = NULL;
       
   531     noEntitiesBuf = HBufC::NewL(noEntitiesPtr.Length());
       
   532     noEntitiesBuf->Des().Copy(noEntitiesPtr);
       
   533     CleanupStack::PopAndDestroy(2, out); // out, noEntitiesContent
       
   534     return noEntitiesBuf;
       
   535     }
       
   536 
       
   537 
       
   538 TInt CWidgetRegistryXml::EncodedStringLength(TPtrC8 aStringToConvert)
       
   539     {
       
   540     _LIT(KEntity, "\"&\r<>");
       
   541     if (aStringToConvert.Length() == 0 ) return 0;
       
   542     TInt entityLength[] = {6,5,5,4,4};
       
   543     TInt i;
       
   544     TInt count = 0;
       
   545     for (i = 0; i < aStringToConvert.Length(); i++)
       
   546         {
       
   547         TInt entityIndex = KEntity().Locate(aStringToConvert[i]);
       
   548         if (entityIndex != KErrNotFound)
       
   549             {
       
   550             count+= entityLength[entityIndex];
       
   551             }
       
   552         else
       
   553             {
       
   554             count++;
       
   555             }
       
   556         }
       
   557     return count;
       
   558     }