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