|
1 /* |
|
2 * Copyright (c) 2002-2006 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 "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: Class implements XML base fragment using libxml2 classes |
|
15 * |
|
16 */ |
|
17 |
|
18 |
|
19 |
|
20 |
|
21 |
|
22 |
|
23 |
|
24 |
|
25 // INCLUDE FILES |
|
26 #include <flogger.h> |
|
27 #include <utf.h> |
|
28 #include <s32mem.h> |
|
29 #include "SenFragmentBase.h" |
|
30 #include "SenParser.h" |
|
31 #include "wslibxml2utils.h" |
|
32 |
|
33 #include <SenXmlConstants.h> |
|
34 |
|
35 #include <xml/attribute.h> // needed for RAttributeArray |
|
36 #include <xml/parserfeature.h> // for TParserFeature enumeration |
|
37 #include <xmlengserializationoptions.h> // for TSerializationOptions |
|
38 #include <xmlengbinarycontainer.h> |
|
39 #include <xmlengnodelist.h> |
|
40 |
|
41 |
|
42 typedef unsigned char xmlChar; // from "libxml/Libxml2_xmlstring.h" |
|
43 |
|
44 using namespace Xml; |
|
45 |
|
46 // *************************************************************************** |
|
47 // Fragment class state constants are as following (declared in subclasses): |
|
48 // KSenStateNotSet = -1; |
|
49 // KSenStateIgnore = 0; // even ones ignore(0), |
|
50 // KSenStateSave = 1; // and odd ones save(1) |
|
51 // KSenStateResume = 2; |
|
52 // KStateParsingFramework = 4; |
|
53 // KStateParsingSoapFault = 5; // odd, save |
|
54 // KStateParsingServiceDescription = 6; |
|
55 // KStateParsingResourceOffering = 11; // odd, save |
|
56 // KStateParsingCredentials = 12; |
|
57 // KStateParsingService = 13; // odd state, saves content |
|
58 // KStateParsingPwTransforms = 14; |
|
59 // KStateParsingSoapHeader = 20; // ignore state (even num) |
|
60 // KStateParsingSoapBody = 40; // ignore state (even num) |
|
61 // KStateParsingSingleCredential = 122; |
|
62 // KStateParsingProviderPolicy = 1222; |
|
63 |
|
64 namespace |
|
65 { |
|
66 const TInt KFlatBufSize = 128; |
|
67 _LIT(KSenFragmentPanic, "SenFragment"); |
|
68 |
|
69 TBool EncodeXmlEscapesL( const TDesC8& aOriginal, HBufC8*& aEncoded ) |
|
70 { |
|
71 TBool retVal = EFalse; |
|
72 delete aEncoded; |
|
73 aEncoded = NULL; |
|
74 |
|
75 if (aOriginal == KNullDesC8) |
|
76 { |
|
77 return retVal; |
|
78 } |
|
79 TPtrC8 tokens[] = |
|
80 { |
|
81 KSenEscapedAmp(), |
|
82 KSenEscapedApos(), |
|
83 KSenEscapedDblQuot(), |
|
84 KSenEscapedGt(), |
|
85 KSenEscapedLt() |
|
86 }; |
|
87 TText16 tokenChars[] = |
|
88 { |
|
89 '&', |
|
90 '\'', |
|
91 '\"', |
|
92 '>', |
|
93 '<' |
|
94 }; |
|
95 |
|
96 // Replace escaped characters, if any |
|
97 for (TInt i = 0; i < aOriginal.Length(); i++) |
|
98 { |
|
99 TBool foundChar = EFalse; |
|
100 //for (TInt j = 0; j < (sizeof(tokenChars) / sizeof(TText16)); j++) |
|
101 for (TInt j = 0; j < 5; j++) |
|
102 { |
|
103 if (aOriginal[i] == tokenChars[j]) |
|
104 { |
|
105 if ( !aEncoded ) |
|
106 { |
|
107 aEncoded = |
|
108 HBufC8::NewL(aOriginal.Length() * KSenMaxXmlEscapedLength); |
|
109 aEncoded->Des().Append(aOriginal.Left(i)); |
|
110 } |
|
111 foundChar = ETrue; |
|
112 aEncoded->Des().Append(tokens[j]); |
|
113 retVal = ETrue; // indicate, that encoding was done |
|
114 break; |
|
115 } |
|
116 } |
|
117 if (!foundChar) |
|
118 { |
|
119 if (aEncoded) |
|
120 { |
|
121 |
|
122 aEncoded->Des().Append(aOriginal[i]); |
|
123 } |
|
124 } |
|
125 } |
|
126 return retVal; |
|
127 } |
|
128 } |
|
129 |
|
130 EXPORT_C CSenFragmentBase* CSenFragmentBase::NewL(const TXmlEngElement& aElement) |
|
131 { |
|
132 CSenFragmentBase* pNew = new (ELeave) CSenFragmentBase; |
|
133 CleanupStack::PushL(pNew); |
|
134 pNew->BaseConstructL(aElement); |
|
135 CleanupStack::Pop(pNew); |
|
136 return pNew; |
|
137 } |
|
138 |
|
139 EXPORT_C CSenFragmentBase* CSenFragmentBase::NewL(const TDesC8& aLocalName) |
|
140 { |
|
141 CSenFragmentBase* pNew = new (ELeave) CSenFragmentBase; |
|
142 CleanupStack::PushL(pNew); |
|
143 pNew->BaseConstructL(aLocalName); |
|
144 CleanupStack::Pop(pNew); |
|
145 return pNew; |
|
146 } |
|
147 |
|
148 EXPORT_C CSenFragmentBase* CSenFragmentBase::NewL(const TDesC8& aNsUri, |
|
149 const TDesC8& aLocalName |
|
150 ) |
|
151 { |
|
152 CSenFragmentBase* pNew = new (ELeave) CSenFragmentBase; |
|
153 CleanupStack::PushL(pNew); |
|
154 pNew->BaseConstructL(aNsUri, aLocalName); |
|
155 CleanupStack::Pop(pNew); |
|
156 return pNew; |
|
157 } |
|
158 |
|
159 EXPORT_C CSenFragmentBase* CSenFragmentBase::NewL(const TDesC8& aNsUri, |
|
160 const TDesC8& aLocalName, |
|
161 const TDesC8& aPrefix, |
|
162 const RAttributeArray& aAttrs |
|
163 ) |
|
164 { |
|
165 CSenFragmentBase* pNew = new (ELeave) CSenFragmentBase; |
|
166 CleanupStack::PushL(pNew); |
|
167 pNew->BaseConstructL(aNsUri, aLocalName, aPrefix, aAttrs); |
|
168 CleanupStack::Pop(pNew); |
|
169 return pNew; |
|
170 } |
|
171 |
|
172 EXPORT_C CSenFragmentBase* CSenFragmentBase::NewL(const TDesC8& aNsUri, |
|
173 const TDesC8& aLocalName, |
|
174 const TDesC8& aPrefix, |
|
175 const RAttributeArray& aAttrs, |
|
176 TXmlEngElement& aParent |
|
177 ) |
|
178 { |
|
179 CSenFragmentBase* pNew = new (ELeave) CSenFragmentBase; |
|
180 CleanupStack::PushL(pNew); |
|
181 pNew->BaseConstructL(aNsUri, aLocalName, aPrefix, aAttrs, aParent); |
|
182 CleanupStack::Pop(pNew); |
|
183 return pNew; |
|
184 } |
|
185 |
|
186 EXPORT_C CSenFragmentBase* CSenFragmentBase::NewL(const TDesC8& aNsUri, |
|
187 const TDesC8& aLocalName, |
|
188 const TDesC8& aPrefix, |
|
189 const RAttributeArray& aAttrs, |
|
190 TXmlEngElement& aParent, |
|
191 RSenDocument& aOwnerDocument |
|
192 ) |
|
193 { |
|
194 CSenFragmentBase* pNew = new (ELeave) CSenFragmentBase; |
|
195 CleanupStack::PushL(pNew); |
|
196 pNew->BaseConstructL(aNsUri, aLocalName, aPrefix, aAttrs, aParent, |
|
197 aOwnerDocument); |
|
198 CleanupStack::Pop(pNew); |
|
199 return pNew; |
|
200 } |
|
201 |
|
202 EXPORT_C CSenFragmentBase* CSenFragmentBase::NewL(const TDesC8& aNsUri, |
|
203 const TDesC8& aLocalName, |
|
204 const TDesC8& aPrefix |
|
205 ) |
|
206 { |
|
207 CSenFragmentBase* pNew = new (ELeave) CSenFragmentBase; |
|
208 CleanupStack::PushL(pNew); |
|
209 pNew->BaseConstructL(aNsUri, aLocalName, aPrefix); |
|
210 CleanupStack::Pop(pNew); |
|
211 return pNew; |
|
212 } |
|
213 |
|
214 EXPORT_C CSenFragmentBase* CSenFragmentBase::NewL(TXmlEngElement& aRootElement, |
|
215 RSenDocument& aOwnerDocument) |
|
216 { |
|
217 CSenFragmentBase* pNew = new (ELeave) CSenFragmentBase; |
|
218 CleanupStack::PushL(pNew); |
|
219 pNew->BaseConstructL(aRootElement, aOwnerDocument); |
|
220 CleanupStack::Pop(pNew); |
|
221 return pNew; |
|
222 } |
|
223 |
|
224 EXPORT_C CSenFragmentBase::~CSenFragmentBase() |
|
225 { |
|
226 if ( ipNamespaceArray ) |
|
227 { |
|
228 ipNamespaceArray->ResetAndDestroy(); |
|
229 delete ipNamespaceArray; |
|
230 } |
|
231 iDocument.Close(); |
|
232 if ( ipContentBuf ) |
|
233 { |
|
234 |
|
235 delete ipContentBuf; |
|
236 ipContentBuf = NULL; |
|
237 |
|
238 delete ipContentWriteStream; |
|
239 ipContentWriteStream = NULL; |
|
240 } |
|
241 |
|
242 if ( ipDelegate ) |
|
243 { |
|
244 delete ipDelegate; |
|
245 ipDelegate = NULL; |
|
246 } |
|
247 } |
|
248 |
|
249 EXPORT_C CSenFragmentBase::CSenFragmentBase() |
|
250 : iState(KSenStateIgnore), |
|
251 ipParser(NULL), |
|
252 ipOwner(NULL), |
|
253 ipDelegate(NULL) |
|
254 { |
|
255 } |
|
256 |
|
257 EXPORT_C void CSenFragmentBase::BaseConstructL(const TXmlEngElement& aSrc) |
|
258 { |
|
259 iElement = aSrc.CopyL(); |
|
260 iDocument = RSenDocument::NewL(); |
|
261 iDocument.SetDocumentElement(iElement); |
|
262 } |
|
263 |
|
264 EXPORT_C void CSenFragmentBase::BaseConstructL(const TDesC8& aLocalName) |
|
265 { |
|
266 iDocument = RSenDocument::NewL(); |
|
267 if ( aLocalName != KNullDesC8 ) |
|
268 { |
|
269 iDocument.CreateDocumentElementL(aLocalName); |
|
270 iElement = iDocument.DocumentElement(); |
|
271 } |
|
272 } |
|
273 |
|
274 EXPORT_C void CSenFragmentBase::BaseConstructL(const TDesC8& aNsUri, |
|
275 const TDesC8& aLocalName |
|
276 ) |
|
277 { |
|
278 iDocument = RSenDocument::NewL(); |
|
279 iDocument.CreateDocumentElementL(aLocalName, aNsUri); |
|
280 iElement = iDocument.DocumentElement(); |
|
281 } |
|
282 |
|
283 EXPORT_C void CSenFragmentBase::BaseConstructL(const TDesC8& aNsUri, |
|
284 const TDesC8& aLocalName, |
|
285 const TDesC8& aPrefix, |
|
286 const RAttributeArray& aAttrs |
|
287 ) |
|
288 { |
|
289 iDocument = RSenDocument::NewL(); |
|
290 if (aPrefix == KNullDesC8) |
|
291 { |
|
292 iDocument.CreateDocumentElementL(aLocalName, aNsUri); |
|
293 } |
|
294 else |
|
295 { |
|
296 iDocument.CreateDocumentElementL(aLocalName, aNsUri, aPrefix); |
|
297 } |
|
298 |
|
299 iElement = iDocument.DocumentElement(); |
|
300 AddAttributesL(aAttrs); |
|
301 } |
|
302 |
|
303 EXPORT_C void CSenFragmentBase::BaseConstructL( |
|
304 const TDesC8& aNsUri, |
|
305 const TDesC8& aLocalName, |
|
306 const TDesC8& aPrefix, |
|
307 const RAttributeArray& aAttributes, |
|
308 TXmlEngElement& aParent |
|
309 ) |
|
310 { |
|
311 iDocument = RSenDocument::NewL(); |
|
312 iElement = aParent.AddNewElementL(aLocalName); |
|
313 |
|
314 if (aNsUri != KNullDesC8 || aPrefix != KNullDesC8) |
|
315 { |
|
316 if (aPrefix == KNullDesC8) |
|
317 { |
|
318 // Check if namespace declaration for the root tag |
|
319 // is already defined in parent element. |
|
320 TXmlEngNamespace ns = aParent.LookupNamespaceByUriL(aNsUri); |
|
321 if ( ns.IsNull() ) |
|
322 { |
|
323 // Namespace declaration will be added to iElement |
|
324 iElement.AddNamespaceDeclarationL(aNsUri, KNullDesC8); |
|
325 } |
|
326 |
|
327 WsXmlUtils domUtils; |
|
328 domUtils.XmlEngRenameElementL(iElement, aLocalName, aNsUri, KNullDesC8); |
|
329 } |
|
330 else |
|
331 { |
|
332 // Check if namespace declaration for the root tag |
|
333 // is already defined in parent element. |
|
334 TXmlEngNamespace ns = aParent.LookupNamespaceByUriL(aNsUri); |
|
335 if ( ns.IsNull() ) |
|
336 { |
|
337 // Namespace declaration will be added to iElement |
|
338 iElement.AddNamespaceDeclarationL(aNsUri, aPrefix); |
|
339 } |
|
340 |
|
341 WsXmlUtils domUtils; |
|
342 domUtils.XmlEngRenameElementL(iElement, aLocalName, aNsUri, aPrefix); |
|
343 } |
|
344 } |
|
345 |
|
346 aParent.AppendChildL(iElement); |
|
347 |
|
348 AddAttributesL(aAttributes); |
|
349 } |
|
350 |
|
351 EXPORT_C void CSenFragmentBase::BaseConstructL( |
|
352 const TDesC8& aNsUri, |
|
353 const TDesC8& aLocalName, |
|
354 const TDesC8& aPrefix, |
|
355 const RAttributeArray& aAttributes, |
|
356 TXmlEngElement& aParent, |
|
357 RSenDocument& aOwnerDocument |
|
358 ) |
|
359 { |
|
360 iDocument = aOwnerDocument.Copy(); |
|
361 iElement = aParent.AddNewElementL(aLocalName); |
|
362 |
|
363 if ( aNsUri != KNullDesC8 || aPrefix != KNullDesC8 ) |
|
364 { |
|
365 if ( aPrefix == KNullDesC8 ) |
|
366 { |
|
367 // Check if namespace declaration for the root tag |
|
368 // is already defined in parent element. |
|
369 TXmlEngNamespace ns = aParent.LookupNamespaceByUriL(aNsUri); |
|
370 if ( ns.IsNull() ) |
|
371 { |
|
372 // Namespace declaration will be added to iElement |
|
373 iElement.AddNamespaceDeclarationL(aNsUri, KNullDesC8); |
|
374 } |
|
375 |
|
376 WsXmlUtils domUtils; |
|
377 domUtils.XmlEngRenameElementL(iElement, aLocalName, aNsUri, KNullDesC8); |
|
378 } |
|
379 else |
|
380 { |
|
381 // Check if namespace declaration for the root tag |
|
382 // is already defined in parent element. |
|
383 TXmlEngNamespace ns = aParent.LookupNamespaceByUriL(aNsUri); |
|
384 if ( ns.IsNull() ) |
|
385 { |
|
386 // Namespace declaration will be added to iElement |
|
387 iElement.AddNamespaceDeclarationL(aNsUri, aPrefix); |
|
388 } |
|
389 WsXmlUtils domUtils; |
|
390 domUtils.XmlEngRenameElementL(iElement, aLocalName, aNsUri, aPrefix); |
|
391 } |
|
392 } |
|
393 |
|
394 aParent.AppendChildL(iElement); |
|
395 |
|
396 AddAttributesL(aAttributes); |
|
397 } |
|
398 |
|
399 EXPORT_C void CSenFragmentBase::BaseConstructL(const TDesC8& aNsUri, |
|
400 const TDesC8& aLocalName, |
|
401 const TDesC8& aPrefix |
|
402 ) |
|
403 { |
|
404 iDocument = RSenDocument::NewL(); |
|
405 if ( aNsUri == KNullDesC8 && aPrefix == KNullDesC8 ) |
|
406 { |
|
407 iDocument.CreateDocumentElementL(aLocalName); |
|
408 } |
|
409 else |
|
410 { |
|
411 if ( aPrefix == KNullDesC8 ) |
|
412 { |
|
413 iDocument.CreateDocumentElementL(aLocalName, aNsUri, KNullDesC8); |
|
414 } |
|
415 else |
|
416 { |
|
417 iDocument.CreateDocumentElementL(aLocalName, aNsUri, aPrefix); |
|
418 } |
|
419 } |
|
420 iElement = iDocument.DocumentElement(); |
|
421 } |
|
422 |
|
423 EXPORT_C void CSenFragmentBase::BaseConstructL(TXmlEngElement& aRootElement, |
|
424 RSenDocument& aOwnerDocument) |
|
425 { |
|
426 iDocument = aOwnerDocument.Copy(); |
|
427 iElement = aRootElement; |
|
428 } |
|
429 |
|
430 EXPORT_C void CSenFragmentBase::AddNamespacesL() |
|
431 { |
|
432 if (ipParser) |
|
433 { |
|
434 if ( ipParser->IsFeatureEnabled(EReportNamespaceMapping) ) |
|
435 { |
|
436 // Add namespaces, if any |
|
437 if ( ipNamespaceArray ) |
|
438 { |
|
439 TInt count = ipNamespaceArray->Count(); |
|
440 for (TInt i=0; i < count; i++) |
|
441 { |
|
442 CSenNamespaceData* pNamespace = (*ipNamespaceArray)[i]; |
|
443 TXmlEngNamespace ns = |
|
444 AsElementL().LookupNamespaceByUriL(*pNamespace->ipNamespaceUri); |
|
445 if ( ns.IsNull() ) |
|
446 { |
|
447 if (pNamespace->ipPrefix == NULL) |
|
448 { |
|
449 AsElementL().AddNamespaceDeclarationL(*pNamespace->ipNamespaceUri, |
|
450 KNullDesC8); |
|
451 } |
|
452 else |
|
453 { |
|
454 AsElementL().AddNamespaceDeclarationL(*pNamespace->ipNamespaceUri, |
|
455 *pNamespace->ipPrefix); |
|
456 } |
|
457 } |
|
458 } |
|
459 ipNamespaceArray->ResetAndDestroy(); |
|
460 } |
|
461 } |
|
462 } |
|
463 } |
|
464 |
|
465 EXPORT_C void CSenFragmentBase::AddAttributesToElementL(TXmlEngElement aElement, |
|
466 const RAttributeArray& apAttrs) |
|
467 { |
|
468 TInt count(apAttrs.Count()); |
|
469 |
|
470 for(TInt i=0; i<count; i++) |
|
471 { |
|
472 TPtrC8 localName = apAttrs[i].Attribute().LocalName().DesC(); |
|
473 TPtrC8 value = apAttrs[i].Value().DesC(); |
|
474 |
|
475 if (apAttrs[i].Attribute().Uri().DesC() == KNullDesC8) |
|
476 { |
|
477 aElement.AddNewAttributeL(localName, value); |
|
478 } |
|
479 else |
|
480 { |
|
481 TPtrC8 namespaceUri = apAttrs[i].Attribute().Uri().DesC(); |
|
482 TPtrC8 prefix(KNullDesC8); |
|
483 if ( apAttrs[i].Attribute().Prefix().DesC() != KNullDesC8 ) |
|
484 { |
|
485 prefix.Set(apAttrs[i].Attribute().Prefix().DesC()); |
|
486 } |
|
487 |
|
488 TXmlEngNamespace ns = aElement.LookupNamespaceByUriL(namespaceUri); |
|
489 if ( ns.NotNull() ) |
|
490 { |
|
491 if (ns.Prefix() == KNullDesC8 && prefix == KNullDesC8) |
|
492 { |
|
493 aElement.AddNewAttributeWithNsL(localName, value, namespaceUri); |
|
494 } |
|
495 else if ( ns.Prefix() == prefix ) |
|
496 { |
|
497 aElement.AddNewAttributeL(localName, value, ns); |
|
498 } |
|
499 else |
|
500 { |
|
501 aElement.AddNewAttributeL(localName, value, namespaceUri, prefix); |
|
502 } |
|
503 } |
|
504 else |
|
505 { |
|
506 if ( prefix == KNullDesC8 ) |
|
507 { |
|
508 aElement.AddNamespaceDeclarationL(namespaceUri, KNullDesC8); |
|
509 aElement.AddNewAttributeWithNsL(localName, value, namespaceUri); |
|
510 } |
|
511 else |
|
512 { |
|
513 aElement.AddNewAttributeL(localName, value, namespaceUri, prefix); |
|
514 } |
|
515 } |
|
516 } |
|
517 } |
|
518 } |
|
519 |
|
520 EXPORT_C void CSenFragmentBase::AddAttributesL(const RAttributeArray& apAttrs) |
|
521 { |
|
522 AddAttributesToElementL(AsElementL(), apAttrs); |
|
523 } |
|
524 |
|
525 EXPORT_C RSenDocument& CSenFragmentBase::AsDocumentL() |
|
526 { |
|
527 return iDocument; |
|
528 } |
|
529 |
|
530 EXPORT_C TXmlEngElement CSenFragmentBase::AsElementL() |
|
531 { |
|
532 __ASSERT_ALWAYS(iElement.NotNull(), User::Panic(KSenFragmentPanic, EFragmentElementNotInitialized)); |
|
533 |
|
534 return iElement; |
|
535 } |
|
536 |
|
537 void CSenFragmentBase::RenameL(const TDesC8& aLocalName, const TDesC8& aPrefix, const TDesC8& aNamespace) |
|
538 { |
|
539 WsXmlUtils domUtils; |
|
540 domUtils.XmlEngRenameElementL(AsElementL(), aLocalName, aNamespace, aPrefix); // Note that in TElement the *prefix* is the last arg(!) |
|
541 } |
|
542 |
|
543 void CSenFragmentBase::RenameL(const TDesC8& aLocalName, const TDesC8& aNamespace) |
|
544 { |
|
545 WsXmlUtils domUtils; |
|
546 domUtils.XmlEngRenameElementL(AsElementL(), aLocalName, aNamespace, KNullDesC8); // Note that in TElement the *prefix* is the last arg(!) |
|
547 } |
|
548 |
|
549 void CSenFragmentBase::RenameLocalNameL(const TDesC8& aLocalName) |
|
550 { |
|
551 WsXmlUtils domUtils; |
|
552 domUtils.XmlEngRenameElementL(AsElementL(), aLocalName, KNullDesC8, KNullDesC8); // Note that in TElement the *prefix* is the last arg(!) |
|
553 } |
|
554 |
|
555 void CSenFragmentBase::RenameNamespaceL(const TDesC8& aNamespace) |
|
556 { |
|
557 WsXmlUtils domUtils; |
|
558 domUtils.XmlEngRenameElementL(AsElementL(), KNullDesC8, aNamespace, KNullDesC8); // Note that in TElement the *prefix* is the last arg(!) |
|
559 } |
|
560 |
|
561 void CSenFragmentBase::RenameNamespaceL(const TDesC8& aPrefix, const TDesC8& aNamespace) |
|
562 { |
|
563 WsXmlUtils domUtils; |
|
564 domUtils.XmlEngRenameElementL(AsElementL(), KNullDesC8, aNamespace, aPrefix); // Note that in TElement the *prefix* is the last arg(!) |
|
565 } |
|
566 |
|
567 void CSenFragmentBase::RenamePrefixL(const TDesC8& aPrefix) |
|
568 { |
|
569 WsXmlUtils domUtils; |
|
570 domUtils.XmlEngRenameElementL(AsElementL(), KNullDesC8, KNullDesC8, aPrefix); // Note that in TElement the *prefix* is the last arg(!) |
|
571 } |
|
572 |
|
573 EXPORT_C TXmlEngElement CSenFragmentBase::ExtractElement() |
|
574 { |
|
575 TXmlEngElement element = iDocument.DocumentElement(); |
|
576 |
|
577 if ( element.IsSameNode(iElement) ) |
|
578 { |
|
579 // Unlink only when element is root element of this document. |
|
580 // |
|
581 // This fragment maybe delegate and element is still part |
|
582 // of other Fragment's DOM Tree. |
|
583 iElement.Unlink(); |
|
584 } |
|
585 |
|
586 TXmlEngElement retElement = iElement; |
|
587 TXmlEngElement nullElement; |
|
588 iElement = nullElement; |
|
589 |
|
590 return retElement; |
|
591 } |
|
592 |
|
593 EXPORT_C void CSenFragmentBase::SetParser(CSenParser& aParser) |
|
594 { |
|
595 ipParser = &aParser; |
|
596 } |
|
597 |
|
598 EXPORT_C void CSenFragmentBase::OnDelegateParsingL(CSenFragmentBase& aDelegate) |
|
599 { |
|
600 // Delegate parsing to a new Fragment, until we encounter |
|
601 // the end of an element with the given qualified name |
|
602 aDelegate.SetOwner(*this); |
|
603 aDelegate.ipParser = ipParser; |
|
604 aDelegate.StartSavingContent(); |
|
605 SetContentHandler(aDelegate); |
|
606 } |
|
607 |
|
608 EXPORT_C void CSenFragmentBase::OnDelegateParsingL(const RTagInfo& aElement, |
|
609 const RAttributeArray& aAttributes, |
|
610 TInt /*aErrorCode*/) |
|
611 { |
|
612 // Delegate parsing to a new Fragment, until we encounter the end of an |
|
613 // element with the given qualified name |
|
614 const TPtrC8 saxLocalName = aElement.LocalName().DesC(); |
|
615 const TPtrC8 saxNsUri = aElement.Uri().DesC(); |
|
616 const TPtrC8 saxPrefix = aElement.Prefix().DesC(); |
|
617 |
|
618 TXmlEngElement element = AsElementL(); |
|
619 RSenDocument document = AsDocumentL(); |
|
620 |
|
621 |
|
622 __ASSERT_ALWAYS( |
|
623 ipDelegate == NULL, |
|
624 User::Panic(KSenFragmentPanic, EDelegatedFragmentAlreadySet) |
|
625 ); |
|
626 ipDelegate = CSenFragmentBase::NewL(saxNsUri, |
|
627 saxLocalName, |
|
628 saxPrefix, |
|
629 aAttributes, |
|
630 element, |
|
631 document); |
|
632 |
|
633 OnDelegateParsingL(*ipDelegate); |
|
634 } |
|
635 |
|
636 EXPORT_C void CSenFragmentBase::StartSavingContent() |
|
637 { |
|
638 iState = KSenStateSave; |
|
639 } |
|
640 |
|
641 EXPORT_C void CSenFragmentBase::SetOwner(CSenFragmentBase& aFragment) |
|
642 { |
|
643 ipOwner = &aFragment; |
|
644 } |
|
645 |
|
646 EXPORT_C void CSenFragmentBase::OnResumeParsingFromL(const RTagInfo& aElement, TInt aErrorCode) |
|
647 { |
|
648 SetContentHandler(*this); |
|
649 |
|
650 // Destroy delegate |
|
651 if ( ipDelegate ) |
|
652 { |
|
653 HBufC8* pAsXml = ipDelegate->AsXmlL(); |
|
654 CleanupStack::PushL(pAsXml); |
|
655 |
|
656 delete ipDelegate; // free memory |
|
657 ipDelegate = NULL; |
|
658 |
|
659 if ( !ipContentBuf ) |
|
660 { |
|
661 ipContentBuf = CBufFlat::NewL(KFlatBufSize); |
|
662 ipContentWriteStream = new (ELeave) RBufWriteStream; |
|
663 ipContentWriteStream->Open(*ipContentBuf); |
|
664 } |
|
665 ipContentWriteStream->WriteL(*pAsXml); |
|
666 |
|
667 CleanupStack::PopAndDestroy(pAsXml); |
|
668 } |
|
669 |
|
670 TInt currentState = KSenStateNotSet; // == -1 |
|
671 if ( iElement.NotNull() ) |
|
672 { |
|
673 const TPtrC8 saxLocalName = aElement.LocalName().DesC(); |
|
674 const TPtrC8 saxNsUri = aElement.Uri().DesC(); |
|
675 TPtrC8 localName = iElement.Name(); |
|
676 TPtrC8 nsUri = iElement.NamespaceUri(); |
|
677 |
|
678 if(localName == saxLocalName && nsUri == saxNsUri) |
|
679 { |
|
680 currentState = iState; |
|
681 // Before calling EndElementL, which may execute |
|
682 // unpredictable amount of code in subclasses, the |
|
683 // the state must be set to "ignore" |
|
684 iState = KSenStateResume; |
|
685 } |
|
686 } |
|
687 |
|
688 OnEndElementL(aElement, aErrorCode); |
|
689 // now check if current state was to be preserved |
|
690 if(currentState!=KSenStateNotSet) // IOP |
|
691 { |
|
692 // restore the state preserved prior to |
|
693 // "set ignore for endelement" -case |
|
694 iState = currentState; |
|
695 } |
|
696 } |
|
697 |
|
698 EXPORT_C void CSenFragmentBase::OnStartElementL(const RTagInfo& aElement, |
|
699 const RAttributeArray& aAttributes, |
|
700 TInt aErrorCode) |
|
701 { |
|
702 const TPtrC8 saxLocalName = aElement.LocalName().DesC(); |
|
703 const TPtrC8 saxNsUri = aElement.Uri().DesC(); |
|
704 const TPtrC8 saxPrefix = aElement.Prefix().DesC(); |
|
705 |
|
706 if ( iElement.IsNull() ) |
|
707 { |
|
708 if ( saxNsUri == KNullDesC8 && saxPrefix == KNullDesC8 ) |
|
709 { |
|
710 iDocument.CreateDocumentElementL(saxLocalName); |
|
711 } |
|
712 else |
|
713 { |
|
714 if ( saxPrefix == KNullDesC8 ) |
|
715 { |
|
716 iDocument.CreateDocumentElementL(saxLocalName, |
|
717 saxNsUri, |
|
718 KNullDesC8); |
|
719 } |
|
720 else |
|
721 { |
|
722 iDocument.CreateDocumentElementL(saxLocalName, |
|
723 saxNsUri, |
|
724 saxPrefix); |
|
725 } |
|
726 } |
|
727 iElement = iDocument.DocumentElement(); |
|
728 } |
|
729 |
|
730 TXmlEngElement element = AsElementL(); |
|
731 |
|
732 TPtrC8 localName = element.Name(); |
|
733 TPtrC8 nsUri(KNullDesC8); |
|
734 if (element.NamespaceUri() != KNullDesC8) |
|
735 { |
|
736 nsUri.Set(element.NamespaceUri()); |
|
737 } |
|
738 |
|
739 if(iState == KSenStateIgnore) |
|
740 { |
|
741 if(localName == saxLocalName && nsUri == saxNsUri) |
|
742 { |
|
743 iState = KSenStateSave; |
|
744 AddNamespacesL(); |
|
745 AddAttributesL(aAttributes); |
|
746 } |
|
747 } |
|
748 else if((iState & KSenStateSave) == KSenStateSave) |
|
749 { |
|
750 if(localName == saxLocalName && nsUri == saxNsUri) |
|
751 { |
|
752 // start a new BaseFragment otherwise we loose |
|
753 // track of nested elements with the same name |
|
754 OnDelegateParsingL(aElement, aAttributes, aErrorCode); |
|
755 } |
|
756 else |
|
757 { |
|
758 OnWriteStartElementL(aElement, aAttributes); |
|
759 } |
|
760 } |
|
761 } |
|
762 |
|
763 EXPORT_C void CSenFragmentBase::OnEndElementL(const RTagInfo& aElement, TInt aErrorCode) |
|
764 { |
|
765 const TPtrC8 saxLocalName = aElement.LocalName().DesC(); |
|
766 const TPtrC8 saxNsUri = aElement.Uri().DesC(); |
|
767 const TPtrC8 saxPrefix = aElement.Prefix().DesC(); |
|
768 |
|
769 TXmlEngElement element = AsElementL(); |
|
770 |
|
771 TPtrC8 localName = element.Name(); |
|
772 TPtrC8 nsUri(KNullDesC8); |
|
773 if (element.NamespaceUri() != KNullDesC8) |
|
774 { |
|
775 nsUri.Set(element.NamespaceUri()); |
|
776 } |
|
777 |
|
778 if(localName == saxLocalName && nsUri == saxNsUri) |
|
779 { |
|
780 if(iState != KSenStateResume && ipOwner) |
|
781 { |
|
782 if ( ipContentBuf ) |
|
783 { |
|
784 SetContentL(ipContentBuf->Ptr(0)); |
|
785 |
|
786 delete ipContentBuf; |
|
787 ipContentBuf = NULL; |
|
788 delete ipContentWriteStream; |
|
789 ipContentWriteStream = NULL; |
|
790 } |
|
791 |
|
792 ipOwner->OnResumeParsingFromL(aElement, aErrorCode); |
|
793 return; // This is mandatory, since ResumeParsingFromL |
|
794 // de-allocates delegate fragment! |
|
795 } |
|
796 iState = KSenStateIgnore; |
|
797 } |
|
798 if((iState & KSenStateSave) == KSenStateSave) |
|
799 { |
|
800 OnWriteEndElementL(aElement); |
|
801 } |
|
802 } |
|
803 |
|
804 EXPORT_C void CSenFragmentBase::OnContentL(const TDesC8& aBytes, TInt /*aErrorCode*/) |
|
805 { |
|
806 if((iState & KSenStateSave) == KSenStateSave) |
|
807 { |
|
808 if ( !ipContentBuf ) |
|
809 { |
|
810 ipContentBuf = CBufFlat::NewL(KFlatBufSize); |
|
811 ipContentWriteStream = new (ELeave) RBufWriteStream; |
|
812 ipContentWriteStream->Open( *ipContentBuf ); |
|
813 } |
|
814 HBufC8* reEncoded = NULL; |
|
815 TBool contentIncludesEncodedChars = EncodeXmlEscapesL( aBytes, reEncoded); |
|
816 if ( contentIncludesEncodedChars ) |
|
817 { |
|
818 CleanupStack::PushL( reEncoded ); |
|
819 ipContentWriteStream->WriteL( *reEncoded ); |
|
820 CleanupStack::PopAndDestroy( reEncoded ); |
|
821 } |
|
822 else |
|
823 { |
|
824 ipContentWriteStream->WriteL( aBytes ); |
|
825 } |
|
826 } |
|
827 } |
|
828 |
|
829 EXPORT_C void CSenFragmentBase::OnStartDocumentL( const RDocumentParameters& /*aDocParam*/, |
|
830 TInt /*aErrorCode*/ ) |
|
831 { |
|
832 if ( !ipContentBuf ) |
|
833 { |
|
834 ipContentBuf = CBufFlat::NewL(KFlatBufSize); |
|
835 ipContentWriteStream = new (ELeave) RBufWriteStream; |
|
836 ipContentWriteStream->Open(*ipContentBuf); |
|
837 } |
|
838 } |
|
839 |
|
840 EXPORT_C void CSenFragmentBase::OnEndDocumentL(TInt /*aErrorCode*/) |
|
841 { |
|
842 if ( ipNamespaceArray) |
|
843 { |
|
844 ipNamespaceArray->ResetAndDestroy(); |
|
845 delete ipNamespaceArray; |
|
846 ipNamespaceArray = NULL; |
|
847 } |
|
848 |
|
849 if ( ipContentBuf ) |
|
850 { |
|
851 if ( ipContentBuf->Ptr(0).Length() > 0 ) |
|
852 { |
|
853 SetContentL(ipContentBuf->Ptr(0)); |
|
854 } |
|
855 |
|
856 delete ipContentBuf; |
|
857 ipContentBuf = NULL; |
|
858 delete ipContentWriteStream; |
|
859 ipContentWriteStream = NULL; |
|
860 } |
|
861 } |
|
862 |
|
863 EXPORT_C void CSenFragmentBase::OnStartPrefixMappingL( |
|
864 const RString& aPrefix, |
|
865 const RString& aUri, |
|
866 TInt /*aErrorCode*/) |
|
867 { |
|
868 if ( !ipNamespaceArray ) |
|
869 { |
|
870 ipNamespaceArray = new (ELeave) RPointerArray<CSenNamespaceData>; |
|
871 } |
|
872 |
|
873 CSenNamespaceData* pNamespaceData = new (ELeave) CSenNamespaceData; |
|
874 CleanupStack::PushL(pNamespaceData); |
|
875 pNamespaceData->ipNamespaceUri = aUri.DesC().AllocL(); |
|
876 if (aPrefix.DesC() != KNullDesC8) |
|
877 { |
|
878 pNamespaceData->ipPrefix = aPrefix.DesC().AllocL(); |
|
879 } |
|
880 User::LeaveIfError(ipNamespaceArray->Append(pNamespaceData)); |
|
881 CleanupStack::Pop(pNamespaceData); |
|
882 } |
|
883 |
|
884 EXPORT_C void CSenFragmentBase::OnEndPrefixMappingL( |
|
885 const RString& /*aPrefix*/, |
|
886 TInt /*aErrorCode*/) |
|
887 { |
|
888 } |
|
889 |
|
890 EXPORT_C void CSenFragmentBase::OnIgnorableWhiteSpaceL( |
|
891 const TDesC8& /*aBytes*/, |
|
892 TInt /*aErrorCode*/) |
|
893 { |
|
894 } |
|
895 |
|
896 EXPORT_C void CSenFragmentBase::OnSkippedEntityL( |
|
897 const RString& /*aName*/, |
|
898 TInt /*aErrorCode*/) |
|
899 { |
|
900 } |
|
901 |
|
902 EXPORT_C void CSenFragmentBase::OnProcessingInstructionL( |
|
903 const TDesC8& /*aTarget*/, |
|
904 const TDesC8& /*aData*/, |
|
905 TInt /*aErrorCode*/) |
|
906 { |
|
907 } |
|
908 |
|
909 EXPORT_C void CSenFragmentBase::OnError(TInt /*aErrorCode*/) |
|
910 { |
|
911 } |
|
912 |
|
913 EXPORT_C TAny* CSenFragmentBase::GetExtendedInterface(const TInt32 /*aUid*/) |
|
914 { |
|
915 return NULL; |
|
916 } |
|
917 |
|
918 |
|
919 EXPORT_C void CSenFragmentBase::ResetContentL() |
|
920 { |
|
921 TXmlEngElement element = AsElementL(); |
|
922 element.RemoveChildren(); |
|
923 } |
|
924 |
|
925 EXPORT_C TPtrC8 CSenFragmentBase::ContentL() |
|
926 { |
|
927 TXmlEngElement element = AsElementL(); |
|
928 return element.Text(); |
|
929 } |
|
930 |
|
931 |
|
932 EXPORT_C HBufC* CSenFragmentBase::AsXmlUnicodeL() |
|
933 { |
|
934 HBufC8* pAsXml = AsXmlL(); |
|
935 CleanupStack::PushL(pAsXml); |
|
936 HBufC16* pBuf = HBufC16::NewL(2 * pAsXml->Length()); |
|
937 CleanupStack::PushL(pBuf); |
|
938 TPtr16 des = pBuf->Des(); |
|
939 TInt ret = CnvUtfConverter::ConvertToUnicodeFromUtf8(des, *pAsXml); |
|
940 User::LeaveIfError(ret); |
|
941 CleanupStack::Pop(pBuf); |
|
942 CleanupStack::PopAndDestroy(pAsXml); |
|
943 return pBuf; |
|
944 } |
|
945 |
|
946 EXPORT_C HBufC8* CSenFragmentBase::AsXmlL() |
|
947 { |
|
948 TXmlEngElement element = AsElementL(); |
|
949 |
|
950 TUint optionFlags = 0; |
|
951 // Omit following declarations from the beginning of XML Document: |
|
952 // <?xml version=\"1.0\... |
|
953 // encoding="..." |
|
954 // standalone="..." |
|
955 // ?> |
|
956 optionFlags = optionFlags | TXmlEngSerializationOptions::KOptionOmitXMLDeclaration; |
|
957 |
|
958 // Allow encoding declaration (if KOptionOmitXMLDeclaration is _not_ set) |
|
959 //optionFlags = optionFlags | TSerializationOptions::KOptionEncoding; |
|
960 |
|
961 // Allow standalone declaration (if KOptionOmitXMLDeclaration is _not_ set) |
|
962 //optionFlags = optionFlags | TSerializationOptions::KOptionStandalone; |
|
963 |
|
964 TXmlEngSerializationOptions options(optionFlags); |
|
965 |
|
966 RBuf8 asXml; |
|
967 iDocument.SaveL(asXml, element, options); |
|
968 CleanupClosePushL(asXml); |
|
969 HBufC8* pAsXml = asXml.AllocL(); |
|
970 CleanupStack::PopAndDestroy(&asXml); |
|
971 |
|
972 return pAsXml; |
|
973 } |
|
974 |
|
975 |
|
976 EXPORT_C void CSenFragmentBase::WriteAsXMLToL(RWriteStream& aWs) |
|
977 { |
|
978 HBufC8* pAsXml = AsXmlL(); |
|
979 CleanupStack::PushL(pAsXml); |
|
980 aWs.WriteL(*pAsXml); |
|
981 CleanupStack::PopAndDestroy(pAsXml); |
|
982 } |
|
983 |
|
984 EXPORT_C TPtrC8 CSenFragmentBase::ContentOf(const TDesC8& aLocalName) |
|
985 { |
|
986 TInt err( KErrNone ); |
|
987 RXmlEngNodeList<TXmlEngElement> list; |
|
988 TRAP( |
|
989 err, |
|
990 TXmlEngElement element = AsElementL(); |
|
991 element.GetElementsByTagNameL(list, aLocalName); |
|
992 ) |
|
993 if ( !err && list.Count() > 0 ) |
|
994 { |
|
995 TXmlEngElement firstElement = list.Next(); |
|
996 return firstElement.Text(); |
|
997 } |
|
998 return KNullDesC8(); |
|
999 } |
|
1000 |
|
1001 EXPORT_C TXmlEngElement CSenFragmentBase::SetContentOfL(const TDesC8& aLocalName, |
|
1002 const TDesC8& aContent) |
|
1003 { |
|
1004 TXmlEngElement element = AsElementL(); |
|
1005 RXmlEngNodeList<TXmlEngElement> list; |
|
1006 CleanupClosePushL(list); |
|
1007 |
|
1008 element.GetElementsByTagNameL(list, aLocalName); |
|
1009 |
|
1010 if ( list.Count() > 0 ) |
|
1011 { |
|
1012 TXmlEngElement firstElement = list.Next(); |
|
1013 firstElement.SetTextNoEncL(aContent); |
|
1014 return firstElement; |
|
1015 } |
|
1016 CleanupStack::PopAndDestroy(&list); |
|
1017 |
|
1018 TXmlEngElement newElement = element.AddNewElementL(aLocalName); |
|
1019 newElement.SetTextNoEncL(aContent); |
|
1020 return newElement; |
|
1021 } |
|
1022 |
|
1023 EXPORT_C void CSenFragmentBase::OnWriteStartElementL(const RTagInfo& aElement, |
|
1024 const RAttributeArray& aAttributes) |
|
1025 { |
|
1026 const TPtrC8 saxLocalName = aElement.LocalName().DesC(); |
|
1027 const TPtrC8 saxNsUri = aElement.Uri().DesC(); |
|
1028 const TPtrC8 saxPrefix = aElement.Prefix().DesC(); |
|
1029 |
|
1030 if ( !ipContentBuf ) |
|
1031 { |
|
1032 ipContentBuf = CBufFlat::NewL(KFlatBufSize); |
|
1033 ipContentWriteStream = new (ELeave) RBufWriteStream; |
|
1034 ipContentWriteStream->Open(*ipContentBuf); |
|
1035 } |
|
1036 |
|
1037 ipContentWriteStream->WriteL(KSenLessThan); |
|
1038 if (saxPrefix != KNullDesC8) |
|
1039 { |
|
1040 ipContentWriteStream->WriteL(saxPrefix); |
|
1041 ipContentWriteStream->WriteL(KSenColon); |
|
1042 } |
|
1043 ipContentWriteStream->WriteL(saxLocalName); |
|
1044 |
|
1045 TInt startPoint(0); |
|
1046 if ( !ipParser->IsFeatureEnabled(EReportNamespaceMapping) ) |
|
1047 { |
|
1048 if ( !ipNamespaceArray) |
|
1049 { |
|
1050 ipNamespaceArray = new (ELeave) RPointerArray<CSenNamespaceData>; |
|
1051 } |
|
1052 |
|
1053 // Collect namespace declaration from this element (if it's not |
|
1054 // previously defined) |
|
1055 TBool found(EFalse); |
|
1056 if ( saxNsUri != KNullDesC8 ) |
|
1057 { |
|
1058 // Check if element of this document has already handled |
|
1059 // namespace definition. |
|
1060 TXmlEngNamespace ns = AsElementL().LookupNamespaceByUriL(saxNsUri); |
|
1061 if ( ns.NotNull() ) |
|
1062 { |
|
1063 found = ETrue; |
|
1064 } |
|
1065 else |
|
1066 { |
|
1067 // Check if internal namespace array has already handled |
|
1068 // namespace defintion. <= Means that one of the parent |
|
1069 // elements (in flat content) has already namespace |
|
1070 // definition we are dealing with. |
|
1071 TInt jcount = ipNamespaceArray->Count(); |
|
1072 for (TInt j=0; j < jcount; j++) |
|
1073 { |
|
1074 CSenNamespaceData* pNamespace = (*ipNamespaceArray)[j]; |
|
1075 if ( pNamespace->ipPrefix && *(pNamespace->ipPrefix) == saxPrefix ) |
|
1076 { |
|
1077 if ( *pNamespace->ipNamespaceUri == saxNsUri ) |
|
1078 { |
|
1079 found = ETrue; |
|
1080 break; |
|
1081 } |
|
1082 } |
|
1083 } |
|
1084 } |
|
1085 } |
|
1086 |
|
1087 startPoint = ipNamespaceArray->Count(); |
|
1088 if ( !found ) |
|
1089 { |
|
1090 CSenNamespaceData* pNamespaceData = new (ELeave) CSenNamespaceData; |
|
1091 CleanupStack::PushL(pNamespaceData); |
|
1092 TInt retVal = ipNamespaceArray->Append(pNamespaceData); |
|
1093 User::LeaveIfError(retVal); |
|
1094 CleanupStack::Pop(pNamespaceData); |
|
1095 if (retVal == KErrNone ) |
|
1096 { |
|
1097 pNamespaceData->ipNamespaceUri = saxNsUri.AllocL(); |
|
1098 pNamespaceData->ipPrefix = saxPrefix.AllocL(); |
|
1099 pNamespaceData->ipLocalName = saxLocalName.AllocL(); |
|
1100 } |
|
1101 } |
|
1102 |
|
1103 // Collect new (not previously defined) namespaces from attributes |
|
1104 TInt attCount(aAttributes.Count()); |
|
1105 for ( TInt i = 0; i < attCount; i++) |
|
1106 { |
|
1107 found = EFalse; |
|
1108 TPtrC8 nsUri = aAttributes[i].Attribute().Uri().DesC(); |
|
1109 if ( nsUri != KNullDesC8 ) |
|
1110 { |
|
1111 TPtrC8 nsPrefix = aAttributes[i].Attribute().Prefix().DesC(); |
|
1112 TBool found(EFalse); |
|
1113 // Check if element of this document has already handled |
|
1114 // namespace definition. |
|
1115 TXmlEngNamespace ns = AsElementL().LookupNamespaceByUriL(nsUri); |
|
1116 if ( ns.NotNull() ) |
|
1117 { |
|
1118 found = ETrue; |
|
1119 } |
|
1120 else |
|
1121 { |
|
1122 // Check if internal namespace array has already handled |
|
1123 // namespace defintion. <= Means that one of the parent |
|
1124 // elements (in flat content) has already namespace |
|
1125 // definition we are dealing with. |
|
1126 TInt jcount = ipNamespaceArray->Count(); |
|
1127 for (TInt j=0; j < jcount; j++) |
|
1128 { |
|
1129 CSenNamespaceData* pNamespace = (*ipNamespaceArray)[j]; |
|
1130 if ( pNamespace->ipPrefix && *(pNamespace->ipPrefix) == nsPrefix ) |
|
1131 { |
|
1132 if ( *pNamespace->ipNamespaceUri == nsUri ) |
|
1133 { |
|
1134 found = ETrue; |
|
1135 break; |
|
1136 } |
|
1137 } |
|
1138 } |
|
1139 } |
|
1140 |
|
1141 // If namespace was not found |
|
1142 // namespace will be added to internal array |
|
1143 if ( !found ) |
|
1144 { |
|
1145 CSenNamespaceData* pNamespaceData |
|
1146 = new (ELeave) CSenNamespaceData; |
|
1147 CleanupStack::PushL(pNamespaceData); |
|
1148 TInt retVal = ipNamespaceArray->Append(pNamespaceData); |
|
1149 User::LeaveIfError(retVal); |
|
1150 CleanupStack::Pop(pNamespaceData); |
|
1151 if (retVal == KErrNone ) |
|
1152 { |
|
1153 pNamespaceData->ipNamespaceUri = nsUri.AllocL(); |
|
1154 pNamespaceData->ipPrefix = nsPrefix.AllocL(); |
|
1155 if ( startPoint == ipNamespaceArray->Count() ) |
|
1156 { |
|
1157 pNamespaceData->ipLocalName = saxLocalName.AllocL(); |
|
1158 } |
|
1159 } |
|
1160 } |
|
1161 } |
|
1162 } |
|
1163 } |
|
1164 |
|
1165 // Write namespaces, if any |
|
1166 if ( ipNamespaceArray ) |
|
1167 { |
|
1168 TInt count = ipNamespaceArray->Count(); |
|
1169 for (TInt i=startPoint; i < count; i++) |
|
1170 { |
|
1171 CSenNamespaceData* pNamespace = (*ipNamespaceArray)[i]; |
|
1172 ipContentWriteStream->WriteL(KSenSpace); |
|
1173 ipContentWriteStream->WriteL(KSenXmlns); |
|
1174 if ( pNamespace->ipPrefix && *(pNamespace->ipPrefix) != KNullDesC8 ) |
|
1175 { |
|
1176 ipContentWriteStream->WriteL(KSenColon); |
|
1177 ipContentWriteStream->WriteL(*pNamespace->ipPrefix); |
|
1178 } |
|
1179 ipContentWriteStream->WriteL(KSenEqualsDblQuot); |
|
1180 ipContentWriteStream->WriteL(*pNamespace->ipNamespaceUri); |
|
1181 ipContentWriteStream->WriteL(KSenDblQuot); |
|
1182 } |
|
1183 |
|
1184 if ( ipParser->IsFeatureEnabled(EReportNamespaceMapping) ) |
|
1185 { |
|
1186 ipNamespaceArray->ResetAndDestroy(); |
|
1187 } |
|
1188 } |
|
1189 |
|
1190 // Write attributes, if any |
|
1191 TInt attCount(aAttributes.Count()); |
|
1192 for (TInt i = 0; i < attCount; i++) |
|
1193 { |
|
1194 TPtrC8 prefix = aAttributes[i].Attribute().Prefix().DesC(); |
|
1195 TPtrC8 lAttName = aAttributes[i].Attribute().LocalName().DesC(); |
|
1196 TPtrC8 attValue = aAttributes[i].Value().DesC(); |
|
1197 |
|
1198 ipContentWriteStream->WriteL(KSenSpace); |
|
1199 if (prefix != KNullDesC8) |
|
1200 { |
|
1201 ipContentWriteStream->WriteL(prefix); |
|
1202 ipContentWriteStream->WriteL(KSenColon); |
|
1203 } |
|
1204 ipContentWriteStream->WriteL(lAttName); |
|
1205 |
|
1206 ipContentWriteStream->WriteL(KSenEqualsDblQuot); |
|
1207 ipContentWriteStream->WriteL(attValue); |
|
1208 ipContentWriteStream->WriteL(KSenDblQuot); |
|
1209 } |
|
1210 |
|
1211 ipContentWriteStream->WriteL(KSenGreaterThan); |
|
1212 } |
|
1213 |
|
1214 EXPORT_C void CSenFragmentBase::OnWriteEndElementL(const RTagInfo& aElement) |
|
1215 { |
|
1216 const TPtrC8 saxLocalName = aElement.LocalName().DesC(); |
|
1217 const TPtrC8 saxNsUri = aElement.Uri().DesC(); |
|
1218 const TPtrC8 saxPrefix = aElement.Prefix().DesC(); |
|
1219 |
|
1220 if ( !ipContentBuf ) |
|
1221 { |
|
1222 ipContentBuf = CBufFlat::NewL(KFlatBufSize); |
|
1223 ipContentWriteStream = new (ELeave) RBufWriteStream; |
|
1224 ipContentWriteStream->Open(*ipContentBuf); |
|
1225 } |
|
1226 |
|
1227 if ( ipNamespaceArray && !ipParser->IsFeatureEnabled(EReportNamespaceMapping) ) |
|
1228 { |
|
1229 TInt foundIndex(KErrNotFound); |
|
1230 TInt jcount = ipNamespaceArray->Count(); |
|
1231 for (TInt j=jcount-1; j >= 0 ; j--) |
|
1232 { |
|
1233 CSenNamespaceData* pNamespace = (*ipNamespaceArray)[j]; |
|
1234 if ( pNamespace->ipLocalName != NULL ) |
|
1235 { |
|
1236 if ( *pNamespace->ipLocalName == saxLocalName ) |
|
1237 { |
|
1238 foundIndex = j; |
|
1239 } |
|
1240 break; |
|
1241 } |
|
1242 } |
|
1243 if ( foundIndex != KErrNotFound ) |
|
1244 { |
|
1245 for (TInt j=foundIndex; j < jcount; j++) |
|
1246 { |
|
1247 delete (*ipNamespaceArray)[foundIndex]; |
|
1248 ipNamespaceArray->Remove(foundIndex); |
|
1249 } |
|
1250 } |
|
1251 } |
|
1252 |
|
1253 // Check if EndTag should be written or not. |
|
1254 // There is no need to write EndTag if |
|
1255 // previous tag is StartTag for this element |
|
1256 // and there is no content for the element. |
|
1257 TBool writeEndTag = ETrue; |
|
1258 TInt size = ipContentBuf->Size(); |
|
1259 if ( size > 1 ) |
|
1260 { |
|
1261 // Check if first character before this possible |
|
1262 // EndTag is '>' |
|
1263 if ( ipContentBuf->Ptr(size-1) == KSenGreaterThan ) |
|
1264 { |
|
1265 // This element does not have content |
|
1266 // There is possibility that EndTag is not needed |
|
1267 TInt colon = KErrNotFound; |
|
1268 TInt space = KErrNotFound; |
|
1269 TBool insideDblQuot = EFalse; |
|
1270 |
|
1271 // Search backwards first '<'. |
|
1272 // Search also first ':' and space which |
|
1273 // are right after '<' (if those characters |
|
1274 // can be found). |
|
1275 // |
|
1276 // => Following situations are handled: |
|
1277 // 1) <prefix:localname attr...> |
|
1278 // 2) <prefix:localname> |
|
1279 // 3) <localname> |
|
1280 TInt i=size-2; |
|
1281 TPtrC8 currentCharacter(KNullDesC8); |
|
1282 for (; i > 0; i--) |
|
1283 { |
|
1284 currentCharacter.Set(ipContentBuf->Ptr(i).Left(1)); |
|
1285 |
|
1286 if ( currentCharacter == KSenDblQuot ) |
|
1287 { |
|
1288 if ( insideDblQuot ) |
|
1289 { |
|
1290 insideDblQuot = EFalse; |
|
1291 } |
|
1292 else |
|
1293 { |
|
1294 insideDblQuot = ETrue; |
|
1295 } |
|
1296 } |
|
1297 else if ( !insideDblQuot ) |
|
1298 { |
|
1299 if ( currentCharacter == KSenSlash ) |
|
1300 { |
|
1301 i = KErrNotFound; |
|
1302 break; |
|
1303 } |
|
1304 else if ( currentCharacter == KSenLessThan ) |
|
1305 { |
|
1306 break; |
|
1307 } |
|
1308 else if ( currentCharacter == KSenColon ) |
|
1309 { |
|
1310 colon = i; |
|
1311 } |
|
1312 else if ( currentCharacter == KSenSpace ) |
|
1313 { |
|
1314 colon = KErrNotFound; |
|
1315 space = i; |
|
1316 } |
|
1317 } |
|
1318 } |
|
1319 |
|
1320 // Now that we know place of '<' character and |
|
1321 // also places of ':' and space characters (if |
|
1322 // those two characters exist), |
|
1323 // we can find out possible prefix and localname. |
|
1324 if ( i > 0 ) |
|
1325 { |
|
1326 TPtrC8 localNamePtr(KNullDesC8); |
|
1327 TPtrC8 prefixPtr(KNullDesC8); |
|
1328 if ( colon != KErrNotFound ) |
|
1329 { |
|
1330 // Both Prefix and LocalName can be found. |
|
1331 if ( space != KErrNotFound ) |
|
1332 { |
|
1333 localNamePtr.Set(ipContentBuf->Ptr(colon+1).MidTPtr(0, space-colon-1)); |
|
1334 } |
|
1335 else |
|
1336 { |
|
1337 localNamePtr.Set(ipContentBuf->Ptr(colon+1).MidTPtr(0, size-colon-2)); |
|
1338 } |
|
1339 prefixPtr.Set(ipContentBuf->Ptr(i+1).MidTPtr(0, colon-i-1)); |
|
1340 } |
|
1341 else |
|
1342 { |
|
1343 // Only LocalName can be found. |
|
1344 if ( space != KErrNotFound ) |
|
1345 { |
|
1346 localNamePtr.Set(ipContentBuf->Ptr(i+1).MidTPtr(0, space-i-1)); |
|
1347 } |
|
1348 else |
|
1349 { |
|
1350 localNamePtr.Set(ipContentBuf->Ptr(i+1).MidTPtr(0, size-i-2)); |
|
1351 } |
|
1352 } |
|
1353 |
|
1354 // Do comparison for localname and prefix of |
|
1355 // this EndTag |
|
1356 if ( ( localNamePtr == saxLocalName ) && |
|
1357 ( prefixPtr == saxPrefix ) ) |
|
1358 { |
|
1359 // LocalName and prefix matched. So |
|
1360 // the EndTag should not be written. |
|
1361 // => Now the last character '>' of StartTag can |
|
1362 // be replaced with characters '\' and '>' |
|
1363 // which means that element is closed without |
|
1364 // separate EndTag. |
|
1365 ipContentBuf->Delete((ipContentBuf->Size()-1),1); |
|
1366 ipContentBuf->InsertL((ipContentBuf->Size()), KSenSlash); |
|
1367 ipContentWriteStream->WriteL(KSenGreaterThan); |
|
1368 writeEndTag = EFalse; |
|
1369 } |
|
1370 } |
|
1371 } |
|
1372 } |
|
1373 |
|
1374 if ( writeEndTag ) |
|
1375 { |
|
1376 ipContentWriteStream->WriteL(KSenLessThanSlash()); |
|
1377 |
|
1378 if ( saxPrefix.Length() > 0) |
|
1379 { |
|
1380 HBufC8* pQName = HBufC8::NewLC( saxPrefix.Length() |
|
1381 +KSenColon().Length() |
|
1382 +saxLocalName.Length()); |
|
1383 TPtr8 qname = pQName->Des(); |
|
1384 qname.Append(saxPrefix); |
|
1385 qname.Append(KSenColon); |
|
1386 qname.Append(saxLocalName); |
|
1387 ipContentWriteStream->WriteL(qname); |
|
1388 CleanupStack::PopAndDestroy(pQName); |
|
1389 } |
|
1390 else |
|
1391 { |
|
1392 ipContentWriteStream->WriteL(saxLocalName); |
|
1393 } |
|
1394 |
|
1395 ipContentWriteStream->WriteL(KSenGreaterThan()); |
|
1396 } |
|
1397 } |
|
1398 |
|
1399 EXPORT_C TXmlEngNamespace CSenFragmentBase::Namespace(const TDesC8& aPrefix) |
|
1400 { |
|
1401 TXmlEngNamespace ns; |
|
1402 if (aPrefix.Length() == 0) return ns; |
|
1403 TRAP_IGNORE |
|
1404 ( |
|
1405 TXmlEngElement element = AsElementL(); |
|
1406 ns = element.LookupNamespaceByPrefixL(aPrefix); |
|
1407 ) |
|
1408 return ns; |
|
1409 } |
|
1410 |
|
1411 /*EXPORT_C void CSenFragmentBase::DetachL() |
|
1412 { |
|
1413 //First add all the namespaces referred to in the content. |
|
1414 if (iNamespaces.Count() > 0) |
|
1415 { |
|
1416 TInt count(iNamespaces.Count()); |
|
1417 for (TInt i=0; i<count; i++) |
|
1418 { |
|
1419 CSenNamespace* pNamespace = (CSenNamespace*) iNamespaces[i]; |
|
1420 ipElement->AddNamespaceL(*pNamespace, EFalse); |
|
1421 //TRAPD(err, ipElement->AddNamespaceL(*pNamespace, EFalse)); |
|
1422 //if (err) ; |
|
1423 } |
|
1424 } |
|
1425 //Detach the element from its parent. |
|
1426 ipElement->DetachL(); |
|
1427 }*/ |
|
1428 |
|
1429 EXPORT_C TPtrC8 CSenFragmentBase::LocalName() const |
|
1430 { |
|
1431 __ASSERT_ALWAYS(iElement.NotNull(), User::Panic(KSenFragmentPanic, EFragmentElementNotInitialized)); |
|
1432 |
|
1433 return iElement.Name(); |
|
1434 } |
|
1435 |
|
1436 EXPORT_C TPtrC8 CSenFragmentBase::NsUri() const |
|
1437 { |
|
1438 __ASSERT_ALWAYS(iElement.NotNull(), User::Panic(KSenFragmentPanic, EFragmentElementNotInitialized)); |
|
1439 |
|
1440 return iElement.NamespaceUri(); |
|
1441 } |
|
1442 |
|
1443 EXPORT_C TPtrC8 CSenFragmentBase::NsPrefix() const |
|
1444 { |
|
1445 __ASSERT_ALWAYS(iElement.NotNull(), User::Panic(KSenFragmentPanic, EFragmentElementNotInitialized)); |
|
1446 |
|
1447 return iElement.Prefix(); |
|
1448 } |
|
1449 |
|
1450 EXPORT_C TBool CSenFragmentBase::ConsistsOfL(TXmlEngElement& aElement, TXmlEngElement& aCandidate) |
|
1451 { |
|
1452 // First check the names and namespaces |
|
1453 TPtrC8 elementLocalName = aElement.Name(); |
|
1454 TPtrC8 candidateLocalName = aCandidate.Name(); |
|
1455 // Check localnames (element should always have localname |
|
1456 // <=> localname can't be Null). |
|
1457 if ( elementLocalName != candidateLocalName ) |
|
1458 { |
|
1459 return EFalse; |
|
1460 } |
|
1461 |
|
1462 TPtrC8 elementNamespaceUri = aElement.NamespaceUri(); |
|
1463 TPtrC8 candidateNamespaceUri = aCandidate.NamespaceUri(); |
|
1464 // Check namespaceUris (element does not always have namespaceUri |
|
1465 // <=> namespaceUri can be Null). |
|
1466 if ( elementNamespaceUri != KNullDesC8 && candidateNamespaceUri != KNullDesC8 ) |
|
1467 { |
|
1468 if ( elementNamespaceUri != candidateNamespaceUri ) |
|
1469 { |
|
1470 return EFalse; |
|
1471 } |
|
1472 } |
|
1473 else |
|
1474 { |
|
1475 if ( elementNamespaceUri != KNullDesC8 || candidateNamespaceUri != KNullDesC8 ) |
|
1476 { |
|
1477 return EFalse; |
|
1478 } |
|
1479 } |
|
1480 |
|
1481 TPtrC8 elementPrefix = aElement.Prefix(); |
|
1482 TPtrC8 candidatePrefix = aCandidate.Prefix(); |
|
1483 // Check prefixes (element does not always have prefix |
|
1484 // <=> prefix can be Null). |
|
1485 if ( elementPrefix != KNullDesC8 && candidatePrefix != KNullDesC8 ) |
|
1486 { |
|
1487 if ( elementPrefix != candidatePrefix ) |
|
1488 { |
|
1489 return EFalse; |
|
1490 } |
|
1491 } |
|
1492 else |
|
1493 { |
|
1494 if ( elementPrefix != KNullDesC8 || candidatePrefix != KNullDesC8 ) |
|
1495 { |
|
1496 return EFalse; |
|
1497 } |
|
1498 } |
|
1499 |
|
1500 RBuf8 candidateContent; |
|
1501 aCandidate.WholeTextContentsCopyL(candidateContent); |
|
1502 CleanupClosePushL(candidateContent); |
|
1503 RBuf8 content; |
|
1504 aElement.WholeTextContentsCopyL(content); |
|
1505 CleanupClosePushL(content); |
|
1506 if ( candidateContent != content ) |
|
1507 { |
|
1508 CleanupStack::PopAndDestroy(&content); |
|
1509 CleanupStack::PopAndDestroy(&candidateContent); |
|
1510 return EFalse; // Content doesn't match => no match |
|
1511 } |
|
1512 CleanupStack::PopAndDestroy(&content); |
|
1513 CleanupStack::PopAndDestroy(&candidateContent); |
|
1514 |
|
1515 // Then handle the children |
|
1516 RXmlEngNodeList<TXmlEngElement> candidateChildren; |
|
1517 CleanupClosePushL(candidateChildren); |
|
1518 aCandidate.GetChildElements(candidateChildren); |
|
1519 |
|
1520 RXmlEngNodeList<TXmlEngElement> children; |
|
1521 CleanupClosePushL(children); |
|
1522 aElement.GetChildElements(children); |
|
1523 |
|
1524 // Element should have at least as many child elements |
|
1525 // as candidateElement has. |
|
1526 TInt childrenCount = children.Count(); |
|
1527 TInt candidateChildrenCount = candidateChildren.Count(); |
|
1528 if ( childrenCount < candidateChildrenCount ) |
|
1529 { |
|
1530 CleanupStack::PopAndDestroy(&children); |
|
1531 CleanupStack::PopAndDestroy(&candidateChildren); |
|
1532 return EFalse; |
|
1533 } |
|
1534 |
|
1535 // Every child element of candidate should be found |
|
1536 // from element. |
|
1537 while ( candidateChildren.HasNext() ) |
|
1538 { |
|
1539 TXmlEngElement candidateMatchChild = candidateChildren.Next(); |
|
1540 RXmlEngNodeList<TXmlEngElement> matchChilds; |
|
1541 CleanupClosePushL(matchChilds); |
|
1542 |
|
1543 aElement.GetElementsByTagNameL(matchChilds, |
|
1544 candidateMatchChild.Name(), |
|
1545 candidateMatchChild.NamespaceUri()); |
|
1546 if ( !matchChilds.HasNext() ) |
|
1547 { |
|
1548 CleanupStack::PopAndDestroy(&matchChilds); |
|
1549 CleanupStack::PopAndDestroy(&children); |
|
1550 CleanupStack::PopAndDestroy(&candidateChildren); |
|
1551 return EFalse; |
|
1552 } |
|
1553 else |
|
1554 { |
|
1555 TBool found = EFalse; |
|
1556 while ( matchChilds.HasNext() ) |
|
1557 { |
|
1558 TXmlEngElement matchChild = matchChilds.Next(); |
|
1559 found = ConsistsOfL(matchChild, candidateMatchChild); |
|
1560 if ( found ) break; |
|
1561 } |
|
1562 if ( !found ) |
|
1563 { |
|
1564 CleanupStack::PopAndDestroy(&matchChilds); |
|
1565 CleanupStack::PopAndDestroy(&children); |
|
1566 CleanupStack::PopAndDestroy(&candidateChildren); |
|
1567 return EFalse; |
|
1568 } |
|
1569 } |
|
1570 |
|
1571 CleanupStack::PopAndDestroy(&matchChilds); |
|
1572 } |
|
1573 |
|
1574 CleanupStack::PopAndDestroy(&children); |
|
1575 CleanupStack::PopAndDestroy(&candidateChildren); |
|
1576 return ETrue; |
|
1577 } |
|
1578 |
|
1579 EXPORT_C TBool CSenFragmentBase::ConsistsOfL(CSenFragmentBase& aCandidate) |
|
1580 { |
|
1581 TXmlEngElement element = AsElementL(); |
|
1582 TXmlEngElement candidateElement = aCandidate.AsElementL(); |
|
1583 return ConsistsOfL(element, candidateElement); |
|
1584 } |
|
1585 |
|
1586 EXPORT_C void CSenFragmentBase::SetContentHandler( |
|
1587 CSenFragmentBase& aContentHandler) |
|
1588 { |
|
1589 ipParser->SetContentHandler(aContentHandler); |
|
1590 } |
|
1591 |
|
1592 EXPORT_C void CSenFragmentBase::SetContentL(const TDesC8& aContent) |
|
1593 { |
|
1594 TXmlEngElement element = AsElementL(); |
|
1595 element.SetTextNoEncL(aContent); |
|
1596 } |
|
1597 |
|
1598 EXPORT_C void CSenFragmentBase::AddContentL(const TDesC8& aContent) |
|
1599 { |
|
1600 TPtrC8 content = ContentL(); |
|
1601 TXmlEngElement element = AsElementL(); |
|
1602 if ( content.Length() > 0 ) |
|
1603 { |
|
1604 HBufC8* pContent = HBufC8::NewLC( content.Length() + aContent.Length() ); |
|
1605 TPtr8 ptrContent = pContent->Des(); |
|
1606 ptrContent.Append(content); |
|
1607 ptrContent.Append(aContent); |
|
1608 element.SetTextNoEncL(*pContent); |
|
1609 CleanupStack::PopAndDestroy(pContent); |
|
1610 } |
|
1611 else |
|
1612 { |
|
1613 element.SetTextNoEncL(aContent); |
|
1614 } |
|
1615 } |
|
1616 |
|
1617 EXPORT_C void CSenFragmentBase::SetDocument(RSenDocument& aDocument) |
|
1618 { |
|
1619 iDocument.Close(); |
|
1620 iDocument = aDocument.Copy(); |
|
1621 } |
|
1622 |
|
1623 CSenNamespaceData::~CSenNamespaceData() |
|
1624 { |
|
1625 delete ipNamespaceUri; |
|
1626 delete ipPrefix; |
|
1627 delete ipLocalName; |
|
1628 } |
|
1629 |
|
1630 // End of File |
|
1631 |
|
1632 |