|
1 /* |
|
2 * Copyright (c) 2002-2005 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: |
|
15 * |
|
16 */ |
|
17 |
|
18 |
|
19 |
|
20 |
|
21 |
|
22 |
|
23 |
|
24 |
|
25 // INCLUDE FILES |
|
26 #include <xml/attribute.h> // From syslibs, needed for RAttributeArray |
|
27 |
|
28 #include <SenXmlReader.h> |
|
29 #include <SenXmlConstants.h> |
|
30 #include <SenXmlUtils.h> |
|
31 #include <MSenContentHandlerClient.h> |
|
32 #include "senxmldebug.h" |
|
33 |
|
34 #ifdef EKA2 |
|
35 #ifndef __SERIES60_30__ |
|
36 // S60 3.1 or newer |
|
37 #include <xml/matchdata.h> |
|
38 #endif |
|
39 #else |
|
40 // Use fss with S60 2nd edition FP3 (2.8) - temp file is needed with expat |
|
41 #include <s32file.h> // filestream |
|
42 #endif |
|
43 |
|
44 // DEBUG: |
|
45 #include "sendebug.h" |
|
46 |
|
47 using namespace Xml; |
|
48 |
|
49 namespace |
|
50 { |
|
51 const TInt KArraySize = 128; |
|
52 |
|
53 typedef struct |
|
54 { |
|
55 CSenXmlReader* ipReader; |
|
56 TInt iEnabledFeature; |
|
57 } TReaderData; |
|
58 } |
|
59 |
|
60 _LIT8(KDefaultMimeType, ""); // Expat is made default, so don't have to give mime type |
|
61 |
|
62 EXPORT_C CSenXmlReader* CSenXmlReader::NewL() |
|
63 { |
|
64 CSenXmlReader* pNew = NewLC(); |
|
65 CleanupStack::Pop(); |
|
66 return pNew; |
|
67 } |
|
68 |
|
69 EXPORT_C CSenXmlReader* CSenXmlReader::NewLC() |
|
70 { |
|
71 |
|
72 CSenXmlReader* pNew = new (ELeave) CSenXmlReader(KSenDefaultParserFeature); |
|
73 CleanupStack::PushL(pNew); |
|
74 |
|
75 pNew->ConstructL(KDefaultMimeType);// KXmlParserMimeType : Defaulted to Expat |
|
76 return pNew; |
|
77 } |
|
78 |
|
79 EXPORT_C CSenXmlReader* CSenXmlReader::NewL(TInt aParserFeature) |
|
80 { |
|
81 CSenXmlReader* pNew = NewLC(aParserFeature); |
|
82 CleanupStack::Pop(); |
|
83 return pNew; |
|
84 } |
|
85 |
|
86 EXPORT_C CSenXmlReader* CSenXmlReader::NewLC(TInt aParserFeature) |
|
87 { |
|
88 CSenXmlReader* pNew = new (ELeave) CSenXmlReader(aParserFeature); |
|
89 CleanupStack::PushL(pNew); |
|
90 pNew->ConstructL(KDefaultMimeType);// KXmlParserMimeType : Defaulted to Expat |
|
91 if(aParserFeature<0) |
|
92 { |
|
93 User::Leave(KErrArgument); |
|
94 } |
|
95 return pNew; |
|
96 } |
|
97 |
|
98 EXPORT_C CSenXmlReader* CSenXmlReader::NewL(const TDesC8& aParserMimeType) |
|
99 { |
|
100 CSenXmlReader* pNew = NewLC(aParserMimeType); |
|
101 CleanupStack::Pop(); |
|
102 return pNew; |
|
103 } |
|
104 |
|
105 EXPORT_C CSenXmlReader* CSenXmlReader::NewLC(const TDesC8& aParserMimeType) |
|
106 { |
|
107 CSenXmlReader* pNew = new (ELeave) CSenXmlReader(KSenDefaultParserFeature); |
|
108 CleanupStack::PushL(pNew); |
|
109 pNew->ConstructL(aParserMimeType); |
|
110 return pNew; |
|
111 } |
|
112 |
|
113 EXPORT_C CSenXmlReader* CSenXmlReader::NewL(const TDesC8& aParserMimeType, |
|
114 TInt aParserFeature) |
|
115 { |
|
116 CSenXmlReader* pNew = NewLC(aParserMimeType, aParserFeature); |
|
117 CleanupStack::Pop(); |
|
118 return pNew; |
|
119 } |
|
120 |
|
121 EXPORT_C CSenXmlReader* CSenXmlReader::NewLC(const TDesC8& aParserMimeType, |
|
122 TInt aParserFeature) |
|
123 { |
|
124 CSenXmlReader* pNew = new (ELeave) CSenXmlReader(aParserFeature); |
|
125 CleanupStack::PushL(pNew); |
|
126 pNew->ConstructL(aParserMimeType); |
|
127 if(aParserFeature<0) |
|
128 { |
|
129 User::Leave(KErrArgument); |
|
130 } |
|
131 return pNew; |
|
132 } |
|
133 |
|
134 EXPORT_C CSenXmlReader::CSenXmlReader(TInt aEnabledFeature) |
|
135 : |
|
136 iParser(NULL), |
|
137 iContentHandler(NULL), |
|
138 ipNsPrefixes(NULL), |
|
139 ipNsUris(NULL), |
|
140 iEnabledFeature(aEnabledFeature) |
|
141 { |
|
142 } |
|
143 |
|
144 EXPORT_C CSenXmlReader::~CSenXmlReader() |
|
145 { |
|
146 delete iParser; |
|
147 delete ipNsPrefixes; |
|
148 delete ipNsUris; |
|
149 iStringPool.Close(); |
|
150 } |
|
151 |
|
152 #if defined( __SERIES60_30__ ) |
|
153 void CSenXmlReader::ConstructL(const TDesC8& aParserMimeType) |
|
154 { |
|
155 if(aParserMimeType.Length()==0) |
|
156 { |
|
157 // Use default MIME type |
|
158 iParser = CParser::NewL(KXmlParserMimeType, *this); |
|
159 } |
|
160 else |
|
161 { |
|
162 // Pass aParserMimeType |
|
163 iParser = CParser::NewL(aParserMimeType, *this); |
|
164 } |
|
165 iParser->EnableFeature(iEnabledFeature); |
|
166 iStringPool.OpenL(); |
|
167 } |
|
168 #else |
|
169 void CSenXmlReader::ConstructL(const TDesC8& aParserMimeType) |
|
170 { |
|
171 CMatchData* pMatchData = CMatchData::NewL(); |
|
172 CleanupStack::PushL(pMatchData); |
|
173 |
|
174 if(aParserMimeType.Length()==0) |
|
175 { |
|
176 // Use default MIME type and variant |
|
177 // for this parser instance (text/xml) |
|
178 pMatchData->SetMimeTypeL(KXmlParserMimeType); |
|
179 } |
|
180 else |
|
181 { |
|
182 // Use specified aParserMimeType: |
|
183 pMatchData->SetMimeTypeL(aParserMimeType); |
|
184 |
|
185 // Set the default variant type (libxml2) |
|
186 pMatchData->SetVariantL(KXmlVariant); |
|
187 } |
|
188 |
|
189 iParser = CParser::NewL(*pMatchData, *this); |
|
190 CleanupStack::PopAndDestroy(pMatchData); |
|
191 |
|
192 iParser->EnableFeature(iEnabledFeature); |
|
193 iStringPool.OpenL(); |
|
194 } |
|
195 #endif |
|
196 |
|
197 EXPORT_C void CSenXmlReader::SetContentHandler( |
|
198 MSenContentHandlerClient& aContentHandler) |
|
199 { |
|
200 iContentHandler = &aContentHandler; |
|
201 } |
|
202 |
|
203 #ifdef EKA2 |
|
204 // In S60 3rd edition platform there is a fixed version of expat parser which |
|
205 // can parse XML documents which size is 2048 bytes or greater. The previous |
|
206 // versions crashed with larger documents. |
|
207 EXPORT_C void CSenXmlReader::ParseL(const TDesC8& aBuff) |
|
208 { |
|
209 CleanUp(); |
|
210 |
|
211 #if defined(__SERIES60_30__) |
|
212 RecreateParserL(); |
|
213 #endif // __SERIES_30__ defined |
|
214 |
|
215 // Note(!): Store the currently enabled feature, since the same member |
|
216 // is used to carry a possible error code from OnErrorL() callback: |
|
217 TInt feature(iEnabledFeature); |
|
218 |
|
219 TReaderData* pData = new (ELeave) TReaderData; |
|
220 pData->ipReader = this; |
|
221 pData->iEnabledFeature = iEnabledFeature; |
|
222 CleanupStack::PushL( TCleanupItem( CSenXmlReader::CleanupParser, pData ) ); |
|
223 // Parse the XML document: |
|
224 iParser->ParseL(aBuff); |
|
225 CleanupStack::Pop(); |
|
226 delete pData; |
|
227 |
|
228 iParser->ParseEndL(); // Enables Symbian XML framework errors to propagete OnErrorL() callback |
|
229 |
|
230 CleanUp(); |
|
231 |
|
232 // Check if iEnabledFeature member was used to carry an error from OnErrorL() callback.. |
|
233 if (iEnabledFeature < 0) |
|
234 { |
|
235 TInt error(iEnabledFeature); |
|
236 SENDEBUG((_L("CSenXmlReader::ParserL: leaving (%d)"), error)); |
|
237 // Switch back the originally enabled feature |
|
238 iEnabledFeature = feature; |
|
239 User::Leave(error); |
|
240 } |
|
241 iContentHandler->EndDocument(); |
|
242 } |
|
243 #else |
|
244 EXPORT_C void CSenXmlReader::ParseL(const TDesC8& aBuff) |
|
245 { |
|
246 // In S60 2nd edition FP3 (2.8) platform a temp file has to be used, since the |
|
247 // underlying expat parser would crash when parsing a document which consists |
|
248 // of more that 2048 bytes of XML. |
|
249 |
|
250 if (aBuff.Length() > 2048) // there is 2048 bytes limitation in expat parser! |
|
251 { |
|
252 SENDEBUG_L("CSenXmlReader::ParseL(): parsing over 2048 bytes of XML (EKA1)"); |
|
253 SENDEBUG((_L("- document size: %d bytes."), aBuff.Length() )); |
|
254 |
|
255 // Parse large XML documents using file server |
|
256 RFs fss; |
|
257 User::LeaveIfError(fss.Connect()); |
|
258 CleanupClosePushL(fss); |
|
259 |
|
260 // Now create a new temp file in the specified path using unique |
|
261 // file name which is generated by the file server. Since file |
|
262 // server is not responsible to delete this file, it must be done |
|
263 // after parsing is finished. |
|
264 |
|
265 // Path for temp file |
|
266 _LIT(KFilePath, "c:\\"); |
|
267 |
|
268 // Stores the temp file name when fileOutStream.Temp() returns: |
|
269 TFileName tempFilename; |
|
270 |
|
271 // Try to generate new temporary file, leave if it failes: |
|
272 RFileWriteStream fileOutStream; |
|
273 User::LeaveIfError(fileOutStream.Temp(fss, KFilePath, tempFilename, EFileWrite)); |
|
274 CleanupClosePushL(fileOutStream); |
|
275 SENDEBUG((_L("CSenXmlReader::ParseL(): used temp file name: '%S'"), &tempFilename)); |
|
276 |
|
277 // Write XML document into the file: |
|
278 fileOutStream.WriteL(aBuff); |
|
279 |
|
280 // fileOutStream.Close(). Must be done prior ParseL()! |
|
281 CleanupStack::PopAndDestroy(); |
|
282 |
|
283 // Parse the file: |
|
284 ParseL(fss, tempFilename); |
|
285 |
|
286 // Now delete the temporary file (when it is not in locked in parser's use) |
|
287 fss.Delete(tempFilename); |
|
288 |
|
289 // Finally close the file server session |
|
290 CleanupStack::PopAndDestroy(); // fss.Close() |
|
291 SENDEBUG_L("CSenXmlReader::ParseL() successfully parsed > 2048 bytes of XML."); |
|
292 } |
|
293 else |
|
294 { |
|
295 // Smaller documents may be parsed normally, even with older versions |
|
296 // of Symbian XML framework's expat parser. |
|
297 |
|
298 CleanUp(); |
|
299 |
|
300 #if defined(__SERIES60_30__) |
|
301 RecreateParserL(); |
|
302 #endif // __SERIES_30__ defined |
|
303 |
|
304 TInt feature(iEnabledFeature); |
|
305 |
|
306 TReaderData* pData = new (ELeave) TReaderData; |
|
307 pData->ipReader = this; |
|
308 pData->iEnabledFeature = iEnabledFeature; |
|
309 CleanupStack::PushL( TCleanupItem( CSenXmlReader::CleanupParser, pData ) ); |
|
310 // Parse the XML document: |
|
311 iParser->ParseL(aBuff); |
|
312 CleanupStack::Pop(); |
|
313 delete pData; |
|
314 |
|
315 iParser->ParseEndL(); // Enables Symbian XML framework errors to propagete OnErrorL() callback |
|
316 |
|
317 CleanUp(); |
|
318 |
|
319 if (iEnabledFeature < 0) |
|
320 { |
|
321 TInt error(iEnabledFeature); |
|
322 iEnabledFeature = feature; |
|
323 SENDEBUG((_L("CSenXmlReader::ParserL: leaving (%d)"), iEnabledFeature)); |
|
324 User::Leave(error); |
|
325 } |
|
326 |
|
327 iContentHandler->EndDocument(); |
|
328 } |
|
329 } |
|
330 #endif // not EKA2 |
|
331 |
|
332 |
|
333 EXPORT_C void CSenXmlReader::ParseL(RFs &aRFs, const TDesC& aFileToParse) |
|
334 { |
|
335 CleanUp(); |
|
336 |
|
337 #if defined(__SERIES60_30__) |
|
338 RecreateParserL(); |
|
339 #endif // __SERIES_30__ defined |
|
340 |
|
341 TInt feature(iEnabledFeature); |
|
342 |
|
343 TReaderData* pData = new (ELeave) TReaderData; |
|
344 pData->ipReader = this; |
|
345 pData->iEnabledFeature = iEnabledFeature; |
|
346 CleanupStack::PushL( TCleanupItem( CSenXmlReader::CleanupParser, pData ) ); |
|
347 // Parse the XML document: |
|
348 Xml::ParseL(*iParser, aRFs, aFileToParse); |
|
349 // Note: Xml::ParseL calls ParseL() and ParseEndL() internally: |
|
350 CleanupStack::Pop(); |
|
351 delete pData; |
|
352 |
|
353 CleanUp(); |
|
354 |
|
355 if(iEnabledFeature < 0) |
|
356 { |
|
357 TInt leaveError = iEnabledFeature; |
|
358 iEnabledFeature = feature; |
|
359 User::Leave(leaveError); |
|
360 } |
|
361 |
|
362 iContentHandler->EndDocument(); |
|
363 } |
|
364 |
|
365 // protected helper |
|
366 void CSenXmlReader::RecreateParserL() |
|
367 { |
|
368 delete iParser; |
|
369 iParser = NULL; |
|
370 |
|
371 delete ipNsPrefixes; |
|
372 ipNsPrefixes = NULL; |
|
373 delete ipNsUris; |
|
374 ipNsUris = NULL; |
|
375 |
|
376 #if defined(__SERIES60_30__) |
|
377 // Use default MIME type |
|
378 iParser = CParser::NewL(KXmlParserMimeType, *this); |
|
379 #else |
|
380 CMatchData* pMatchData = CMatchData::NewL(); |
|
381 CleanupStack::PushL(pMatchData); |
|
382 |
|
383 pMatchData->SetMimeTypeL(KXmlParserMimeType); |
|
384 pMatchData->SetVariantL(KXmlVariant); |
|
385 |
|
386 iParser = CParser::NewL(*pMatchData, *this); |
|
387 CleanupStack::PopAndDestroy(pMatchData); |
|
388 #endif |
|
389 |
|
390 iParser->EnableFeature(iEnabledFeature); |
|
391 } |
|
392 |
|
393 void CSenXmlReader::OnStartDocumentL( |
|
394 const RDocumentParameters& /* aDocParam */, |
|
395 TInt /* aErrorCode */) |
|
396 { |
|
397 if(!iContentHandler) |
|
398 { |
|
399 SENDEBUG_L("OnStartDocumentL: KErrSenXmlContentHandlerNotSet"); |
|
400 User::Leave(KErrSenXmlContentHandlerNotSet); |
|
401 } |
|
402 iContentHandler->StartDocument(); |
|
403 } |
|
404 |
|
405 void CSenXmlReader::OnEndDocumentL(TInt /* aErrorCode */) |
|
406 { |
|
407 if(!iContentHandler) |
|
408 { |
|
409 SENDEBUG_L("OnEndDocumentL: KErrSenXmlContentHandlerNotSet"); |
|
410 User::Leave(KErrSenXmlContentHandlerNotSet); |
|
411 } |
|
412 iContentHandler->EndDocument(); |
|
413 } |
|
414 |
|
415 |
|
416 void CSenXmlReader::OnStartElementL(const RTagInfo& aElement, |
|
417 const RAttributeArray& aAttributes, |
|
418 TInt /* aErrorCode */) |
|
419 { |
|
420 if(!iContentHandler) |
|
421 { |
|
422 SENDEBUG_L("OnStartElementL: KErrSenXmlContentHandlerNotSet"); |
|
423 User::Leave(KErrSenXmlContentHandlerNotSet); |
|
424 } |
|
425 |
|
426 |
|
427 const TPtrC8 localName = aElement.LocalName().DesC(); |
|
428 const TPtrC8 nsUri = aElement.Uri().DesC(); |
|
429 const TPtrC8 prefix = aElement.Prefix().DesC(); |
|
430 |
|
431 TPtrC8 qualifiedName = localName; |
|
432 |
|
433 if (prefix != KNullDesC8) |
|
434 { |
|
435 HBufC8* pQName = HBufC8::NewLC(prefix.Length()+localName.Length()+ |
|
436 KSenColon().Length()); |
|
437 TPtr8 qName = pQName->Des(); |
|
438 qName.Append(prefix); |
|
439 qName.Append(KSenColon); |
|
440 qName.Append(localName); |
|
441 qualifiedName.Set(qName); |
|
442 } |
|
443 |
|
444 if(ipNsPrefixes) |
|
445 { |
|
446 // there are namespaces to declare! |
|
447 |
|
448 // make a new array for all attributes including namespace (to be added) |
|
449 RAttributeArray attributesAndNamespaces; |
|
450 |
|
451 CleanupClosePushL(attributesAndNamespaces); |
|
452 TInt nsDeclarationCount(ipNsPrefixes->Count()); |
|
453 for(TInt i=0; i<nsDeclarationCount; i++) |
|
454 { |
|
455 // open and take ownership of RString - xmlnsAttrPrefix |
|
456 RAttribute nsAttribute; |
|
457 //CleanupClosePushL(nsAttribute); |
|
458 |
|
459 TPtrC8 nsPrefix = ipNsPrefixes->MdcaPoint(i); |
|
460 TPtrC8 nsURI = ipNsUris->MdcaPoint(i); |
|
461 |
|
462 if (nsPrefix != KNullDesC8) |
|
463 { |
|
464 nsAttribute.Open(iStringPool.OpenStringL(nsURI), |
|
465 iStringPool.OpenStringL(KSenXmlns()), |
|
466 iStringPool.OpenStringL(nsPrefix), |
|
467 iStringPool.OpenStringL(nsURI) ); |
|
468 |
|
469 } |
|
470 else |
|
471 { |
|
472 nsAttribute.Open(iStringPool.OpenStringL(nsURI), |
|
473 iStringPool.OpenStringL(KNullDesC8()), |
|
474 iStringPool.OpenStringL(KSenXmlns()), |
|
475 iStringPool.OpenStringL(nsURI) ); |
|
476 |
|
477 } |
|
478 |
|
479 |
|
480 // append the namespace attribute (declaration) |
|
481 CleanupClosePushL(nsAttribute); |
|
482 attributesAndNamespaces.AppendL(nsAttribute); |
|
483 CleanupStack::Pop(); // nsAttribute |
|
484 } |
|
485 |
|
486 // the ns declarations have been done using NON-CANONIZING method |
|
487 delete ipNsPrefixes; |
|
488 ipNsPrefixes = NULL; |
|
489 delete ipNsUris; |
|
490 ipNsUris = NULL; |
|
491 |
|
492 |
|
493 |
|
494 // append all other ("real") attributes |
|
495 TInt count(aAttributes.Count()); |
|
496 for(TInt a=0; a<count; a++) |
|
497 { |
|
498 attributesAndNamespaces.AppendL(const_cast <RAttribute&> (aAttributes[a]).Copy()); |
|
499 } |
|
500 |
|
501 |
|
502 // now give the stream content forward to the interested handler object. |
|
503 // we have successfully added the namespace declaration as NON-canonized(!) |
|
504 // attribute (if conditions have been met). |
|
505 iContentHandler->StartElement(nsUri, localName, qualifiedName, attributesAndNamespaces); |
|
506 |
|
507 // close the copied attributes previously added into this array as copies |
|
508 count = attributesAndNamespaces.Count(); |
|
509 for(TInt j=0; j<count; j++) |
|
510 { |
|
511 attributesAndNamespaces[j].Close(); |
|
512 } |
|
513 // close the actual array |
|
514 CleanupStack::PopAndDestroy(); // attributesAndNamespaces.Close(); |
|
515 } |
|
516 else |
|
517 { |
|
518 // give the original attributes to content handler (no new namespaces declared in attrs) |
|
519 iContentHandler->StartElement(nsUri, localName, qualifiedName, aAttributes); |
|
520 } |
|
521 |
|
522 |
|
523 // delete qualified element name, if one was allocated |
|
524 if (prefix != KNullDesC8) |
|
525 { |
|
526 CleanupStack::PopAndDestroy(); // pQName |
|
527 } |
|
528 |
|
529 |
|
530 } |
|
531 |
|
532 |
|
533 |
|
534 void CSenXmlReader::OnEndElementL(const RTagInfo& aElement, TInt /* aErrorCode */) |
|
535 { |
|
536 if(!iContentHandler) |
|
537 { |
|
538 SENDEBUG_L("OnEndElementL: KErrSenXmlContentHandlerNotSet"); |
|
539 User::Leave(KErrSenXmlContentHandlerNotSet); |
|
540 } |
|
541 |
|
542 |
|
543 const TPtrC8 localName = aElement.LocalName().DesC(); |
|
544 const TPtrC8 nsUri = aElement.Uri().DesC(); |
|
545 const TPtrC8 prefix = aElement.Prefix().DesC(); |
|
546 |
|
547 TPtrC8 qualifiedName = localName; |
|
548 |
|
549 if (prefix != KNullDesC8) |
|
550 { |
|
551 HBufC8* pQName = HBufC8::NewLC(prefix.Length()+localName.Length()+ |
|
552 KSenColon().Length()); |
|
553 TPtr8 qName = pQName->Des(); |
|
554 qName.Append(prefix); |
|
555 qName.Append(KSenColon); |
|
556 qName.Append(localName); |
|
557 qualifiedName.Set(qName); |
|
558 } |
|
559 |
|
560 |
|
561 iContentHandler->EndElement(nsUri, |
|
562 localName, |
|
563 qualifiedName); |
|
564 |
|
565 if (prefix != KNullDesC8) |
|
566 { |
|
567 CleanupStack::PopAndDestroy(); // pQName |
|
568 } |
|
569 |
|
570 } |
|
571 |
|
572 |
|
573 void CSenXmlReader::OnContentL(const TDesC8& aBytes, TInt /* aErrorCode */) |
|
574 { |
|
575 if(!iContentHandler) |
|
576 { |
|
577 SENDEBUG_L("OnContentL: KErrSenXmlContentHandlerNotSet"); |
|
578 User::Leave(KErrSenXmlContentHandlerNotSet); |
|
579 } |
|
580 iContentHandler->Characters(aBytes,0,aBytes.Length()); |
|
581 } |
|
582 |
|
583 |
|
584 void CSenXmlReader::OnStartPrefixMappingL( |
|
585 const RString& aPrefix, |
|
586 const RString& aUri, |
|
587 TInt /*aErrorCode*/) |
|
588 { |
|
589 if(!iContentHandler) |
|
590 { |
|
591 SENDEBUG_L("OnStartPrefixMappingL: KErrSenXmlContentHandlerNotSet"); |
|
592 User::Leave(KErrSenXmlContentHandlerNotSet); |
|
593 } |
|
594 |
|
595 if(!ipNsPrefixes) |
|
596 { |
|
597 ipNsPrefixes = new (ELeave) CDesC8ArrayFlat(KArraySize); |
|
598 } |
|
599 |
|
600 if(!ipNsUris) |
|
601 { |
|
602 ipNsUris = new (ELeave) CDesC8ArrayFlat(KArraySize); |
|
603 } |
|
604 |
|
605 ipNsPrefixes->AppendL(aPrefix.DesC()); |
|
606 ipNsUris->AppendL(aUri.DesC()); |
|
607 |
|
608 iContentHandler->StartPrefixMappingL(aPrefix.DesC(), aUri.DesC()); |
|
609 } |
|
610 |
|
611 |
|
612 |
|
613 void CSenXmlReader::OnEndPrefixMappingL(const RString& aPrefix, |
|
614 TInt /*aErrorCode*/) |
|
615 { |
|
616 if(!iContentHandler) |
|
617 { |
|
618 SENDEBUG_L("OnEndPrefixMappingL: KErrSenXmlContentHandlerNotSet"); |
|
619 User::Leave(KErrSenXmlContentHandlerNotSet); |
|
620 } |
|
621 iContentHandler->EndPrefixMappingL(aPrefix.DesC()); |
|
622 } |
|
623 |
|
624 |
|
625 void CSenXmlReader::OnIgnorableWhiteSpaceL(const TDesC8& aBytes, |
|
626 TInt /*aErrorCode*/) |
|
627 { |
|
628 if(!iContentHandler) |
|
629 { |
|
630 SENDEBUG_L("OnIgnorableWhiteSpaceL: KErrSenXmlContentHandlerNotSet"); |
|
631 User::Leave(KErrSenXmlContentHandlerNotSet); |
|
632 } |
|
633 iContentHandler->OnIgnorableWhiteSpaceL(aBytes); |
|
634 } |
|
635 |
|
636 |
|
637 void CSenXmlReader::OnSkippedEntityL(const RString& aName, TInt /*aErrorCode*/) |
|
638 { |
|
639 if(!iContentHandler) |
|
640 { |
|
641 SENDEBUG_L("OnSkippedEntityL: KErrSenXmlContentHandlerNotSet"); |
|
642 User::Leave(KErrSenXmlContentHandlerNotSet); |
|
643 } |
|
644 iContentHandler->SkippedEntity(aName.DesC()); |
|
645 |
|
646 //TInt retVal = iContentHandler->SkippedEntity(aName.DesC()); |
|
647 // content handler spesific code returned error |
|
648 //User::LeaveIfError(retVal); |
|
649 } |
|
650 |
|
651 |
|
652 void CSenXmlReader::OnProcessingInstructionL( |
|
653 const TDesC8& aTarget, |
|
654 const TDesC8& aData, |
|
655 TInt /*aErrorCode */) |
|
656 { |
|
657 if(!iContentHandler) |
|
658 { |
|
659 SENDEBUG_L("OnProcessingInstructionL: KErrSenXmlContentHandlerNotSet"); |
|
660 User::Leave(KErrSenXmlContentHandlerNotSet); |
|
661 } |
|
662 iContentHandler->ProcessingInstructions(aTarget, aData); |
|
663 } |
|
664 |
|
665 // Note: Symbian XML framework error codes are listed in XmlFrameworkErrors.h |
|
666 void CSenXmlReader::OnError(TInt aErrorCode) |
|
667 { |
|
668 #ifdef _SENDEBUG |
|
669 // Symbian XML framework signals about some error: |
|
670 SENDEBUG_L("CSenXmlReader::OnError"); |
|
671 SENDEBUG_L(" -Symbian XML framework signalled an error: "); |
|
672 TBuf<32> buf; |
|
673 buf.AppendNum(aErrorCode); |
|
674 SENDEBUG((buf)); |
|
675 #endif |
|
676 |
|
677 if(!iContentHandler) |
|
678 { |
|
679 SENDEBUG_L("OnError: KErrSenXmlContentHandlerNotSet"); |
|
680 // Cannot report any signalled error to content handler, |
|
681 // since it has not been set. Force ParseL to leave by |
|
682 // setting spesific error code (KErrSenXmlContentHandlerNotSet) |
|
683 iEnabledFeature = KErrSenXmlContentHandlerNotSet; |
|
684 return; |
|
685 } |
|
686 TInt retVal(iContentHandler->Error(aErrorCode)); |
|
687 |
|
688 #ifdef _SENDEBUG |
|
689 // Symbian XML framework signals about some error: |
|
690 SENDEBUG_L(" -Error() callback to content handler returned an error:"); |
|
691 TBuf<32> buf2; |
|
692 buf2.AppendNum(retVal); |
|
693 SENDEBUG((buf2)); |
|
694 #endif |
|
695 retVal = 0; // not used in release builds |
|
696 |
|
697 // In 3.0, iEnabledFeature member was used to indicate ParseL |
|
698 // that it should leave(!). |
|
699 iEnabledFeature = aErrorCode; |
|
700 } |
|
701 |
|
702 |
|
703 TAny* CSenXmlReader::GetExtendedInterface(const TInt32 aUid) |
|
704 { |
|
705 if(!iContentHandler) |
|
706 { |
|
707 SENDEBUG_L("GetExtendedInterface: KErrSenXmlContentHandlerNotSet"); |
|
708 return NULL; |
|
709 } |
|
710 return iContentHandler->GetExtendedInterface(aUid); |
|
711 } |
|
712 |
|
713 |
|
714 EXPORT_C TInt CSenXmlReader::EnabledParserFeature() |
|
715 { |
|
716 return iEnabledFeature; |
|
717 } |
|
718 |
|
719 |
|
720 TInt CSenXmlReader::SetParserFeature(TInt aParserFeature) |
|
721 { |
|
722 if(iParser) |
|
723 { |
|
724 iEnabledFeature = aParserFeature; |
|
725 TInt retCode = iParser->EnableFeature(aParserFeature); |
|
726 return retCode; |
|
727 } |
|
728 else |
|
729 { |
|
730 // internal error: iParser should always be available! |
|
731 TInt leaveCode(KErrNone); |
|
732 // try to re-instantiate the parser - once |
|
733 TRAP(leaveCode, RecreateParserL()); |
|
734 if(leaveCode!=KErrNone) |
|
735 { |
|
736 return leaveCode; |
|
737 } |
|
738 iEnabledFeature = aParserFeature; |
|
739 TInt retCode2 = iParser->EnableFeature(aParserFeature); |
|
740 return retCode2; |
|
741 } |
|
742 } |
|
743 |
|
744 // DEPRECATED |
|
745 EXPORT_C TInt CSenXmlReader::ParserFeature() |
|
746 { |
|
747 return EnabledParserFeature(); |
|
748 } |
|
749 |
|
750 void CSenXmlReader::CleanUp() |
|
751 { |
|
752 delete ipNsPrefixes; |
|
753 ipNsPrefixes = NULL; |
|
754 delete ipNsUris; |
|
755 ipNsUris = NULL; |
|
756 #if defined(__SERIES60_30__) |
|
757 delete iParser; |
|
758 iParser = NULL; |
|
759 #endif // __SERIES_30__ defined |
|
760 } |
|
761 |
|
762 void CSenXmlReader::CleanupParser(TAny* apReaderData) |
|
763 { |
|
764 TReaderData* pData = REINTERPRET_CAST(TReaderData*, apReaderData); |
|
765 pData->ipReader->SetParserFeature(pData->iEnabledFeature); |
|
766 delete pData; |
|
767 } |
|
768 |
|
769 // END OF FILE |
|
770 |
|
771 |