|
1 // Copyright (c) 2003-2009 Nokia Corporation and/or its subsidiary(-ies). |
|
2 // All rights reserved. |
|
3 // This component and the accompanying materials are made available |
|
4 // under the terms of "Eclipse Public License v1.0" |
|
5 // which accompanies this distribution, and is available |
|
6 // at the URL "http://www.eclipse.org/legal/epl-v10.html". |
|
7 // |
|
8 // Initial Contributors: |
|
9 // Nokia Corporation - initial contribution. |
|
10 // |
|
11 // Contributors: |
|
12 // |
|
13 // Description: |
|
14 // |
|
15 |
|
16 #ifndef CEXPAT_H |
|
17 #define CEXPAT_H |
|
18 |
|
19 #include <xml/parserfeature.h> |
|
20 #include <xml/plugins/parserinitparams.h> |
|
21 |
|
22 #include "expat.h" |
|
23 |
|
24 class CXmlParser; |
|
25 |
|
26 /* |
|
27 CExpat class. |
|
28 |
|
29 1. |
|
30 This class encapsulates the Expat xml parser. It is the engine behind |
|
31 CXmlParserPlugin. |
|
32 |
|
33 2. |
|
34 Handles construction and deletion of Expat xml parser. Defines handlers |
|
35 required for Expat, transforms handler data to required types and passes |
|
36 this to the client by MContentHandler callbacks. |
|
37 |
|
38 3. |
|
39 MContentHandler functions can leave. Rather than trapping every one of |
|
40 these, which could prove costly, the functions are allowed to leave 'through' |
|
41 Expat but a tight control is kept on Expat-allocated memory to ensure no |
|
42 leaks occur. This is handled via the sub-class TExpatAlloc. |
|
43 |
|
44 If a MContentHandler function does leave, the Expat parser is entirely |
|
45 deleted for safety and a call to Reset is required to begin using it again. |
|
46 */ |
|
47 |
|
48 class CExpat : public CBase |
|
49 { |
|
50 public: |
|
51 static CExpat* NewL(Xml::MContentHandler& aContentHandler, RStringPool& aStringPool, Xml::CCharSetConverter& aCharSetConverter, |
|
52 RElementStack& aElementStack, TInt aDebugFailCount); |
|
53 ~CExpat(); |
|
54 |
|
55 void ResetL(); |
|
56 TInt EnableFeature(TInt aParserFeature); |
|
57 TInt DisableFeature(TInt aParserFeature); |
|
58 TBool IsFeatureEnabled(TInt aParserFeature) const; |
|
59 |
|
60 /* |
|
61 Allocate a buffer in which to write xml to be parsed by the ParseL and |
|
62 ParseLastL methods. Memory allocated with this method is managed |
|
63 internally. Thus it must not be freed and not put on the cleanup stack. |
|
64 |
|
65 This must be called before every call to ParseL or ParseLastL |
|
66 */ |
|
67 TDes8& GetBufferL(TInt aLength); |
|
68 |
|
69 /* |
|
70 Parsing methods: |
|
71 |
|
72 ParseLastL should be used if the buffer contains the last segment of |
|
73 the document. ParseL should be called in any other case. |
|
74 |
|
75 It is perfectly valid to parse the entire document with ParseL and then |
|
76 call ParseLastL with a zero-length buffer. |
|
77 */ |
|
78 void ParseL(TBool done=EFalse); |
|
79 inline void ParseLastL(); |
|
80 |
|
81 void SetContentSink(class Xml::MContentHandler &); |
|
82 |
|
83 /* |
|
84 Function used to access internal parser heap for testing |
|
85 */ |
|
86 RHeap* GetInternalHeap() const; |
|
87 |
|
88 private: |
|
89 CExpat(Xml::MContentHandler& aContentHandler, RStringPool& aStringPool, Xml::CCharSetConverter& aCharSetConverter, |
|
90 RElementStack& aElementStack); |
|
91 void ConstructL(TInt aDebugFailCount); |
|
92 |
|
93 void CreateRStringL(const TDesC& aInput, RString& aString, TBool aLowerCase); |
|
94 void ScanNameL(const XML_Char* aName, RString& aUriString, RString& aLocalPartString, RString& aPrefixString); |
|
95 inline TInt StringLen(TUint16* p); |
|
96 |
|
97 void ClearElementStack(); |
|
98 |
|
99 static void StartElementHandlerL(void* aUserData, const XML_Char* aName, const XML_Char** aAtts); |
|
100 static void EndElementHandlerL(void* aUserData, const XML_Char* aName); |
|
101 static void CharacterDataHandlerL(void* aUserData, const XML_Char* aString, int aLen); |
|
102 static void ProcessingInstructionHandlerL(void* aUserData, const XML_Char* aTarget, const XML_Char* aData); |
|
103 static void XmlDeclHandlerL(void* aUserData, const XML_Char* aVersion, const XML_Char* aEncoding, int aStandalone); |
|
104 static void StartNamespaceDeclHandlerL(void* aUserData, const XML_Char* aPrefix, const XML_Char* aUri); |
|
105 static void EndNamespaceDeclHandlerL(void* aUserData, const XML_Char* aPrefix); |
|
106 static void SkippedEntityHandlerL(void* aUserData, const XML_Char* aName, int aIsParamEntity); |
|
107 static int ExternalEntityRefHandlerL(void* aUserData, const XML_Char* aName); |
|
108 |
|
109 void HandleStartElementL(const XML_Char* aName, const XML_Char** aAtts); |
|
110 void HandleEndElementL(const XML_Char* aName); |
|
111 void HandleCharacterDataL(const XML_Char* aString, int aLen); |
|
112 void HandleProcessingInstructionL(const XML_Char* aTarget, const XML_Char* aData); |
|
113 void HandleXmlDeclL(const XML_Char* aVersion, const XML_Char* aEncoding, int aStandalone); |
|
114 void HandleStartNamespaceDeclL(const XML_Char* aPrefix, const XML_Char* aUri); |
|
115 void HandleEndNamespaceDeclL(const XML_Char* aPrefix); |
|
116 void HandleSkippedEntityL(const XML_Char* aName, int aIsParamEntity); |
|
117 |
|
118 private: |
|
119 /* |
|
120 Objects supplied on construction |
|
121 */ |
|
122 Xml::MContentHandler* iContentHandler; |
|
123 RStringPool& iStringPool; |
|
124 Xml::CCharSetConverter& iCharSetConverter; |
|
125 RElementStack& iElementStack; |
|
126 |
|
127 TInt iParseMode; |
|
128 |
|
129 /* |
|
130 Used to ensure GetBufferL has been called before a call to ParseL or ParseLastL |
|
131 */ |
|
132 TBool iBufferReady; |
|
133 TPtr8 iInputBuffer; |
|
134 |
|
135 /* |
|
136 Used to record the last status and error raised whilst parsing. |
|
137 */ |
|
138 XML_Status iPrevStatus; |
|
139 TInt iPrevError; |
|
140 |
|
141 /* |
|
142 The expat parser itself |
|
143 */ |
|
144 XML_Parser iParser; |
|
145 |
|
146 /* |
|
147 TExpatAlloc class managing fenced-off memory area separate from the thread's heap. |
|
148 This memory is contained in its own chunk created by UserHeap. |
|
149 */ |
|
150 class TExpatAlloc |
|
151 { |
|
152 public: |
|
153 TExpatAlloc() {} |
|
154 void ConstructL(TInt aHeapSize, TInt aDebugFailCount); |
|
155 ~TExpatAlloc(); |
|
156 |
|
157 /* |
|
158 Called when a leave from within Expat leaves the memory in an unknown state. |
|
159 All memory will be freed. |
|
160 */ |
|
161 void ResetL(); |
|
162 |
|
163 /* |
|
164 Fill supplied XML_Memory_Handling_Suite structure which may then be passed |
|
165 to Expat's XML_ParserCreate_MM |
|
166 */ |
|
167 void FillAllocStruct(XML_Memory_Handling_Suite& aMem) const; |
|
168 |
|
169 static void* Alloc(void* aUserData, size_t aSize); |
|
170 static void* ReAlloc(void* aUserData, void* aPtr, size_t aSize); |
|
171 static void Free(void* aUserData, void *aPtr); |
|
172 |
|
173 /* |
|
174 For testing |
|
175 */ |
|
176 RHeap* GetHeap() const; |
|
177 |
|
178 private: |
|
179 TInt iHeapSize; |
|
180 RHeap* iHeap; |
|
181 } iAllocator; |
|
182 }; |
|
183 |
|
184 inline void CExpat::ParseLastL() |
|
185 { |
|
186 ParseL(ETrue); |
|
187 } |
|
188 |
|
189 /* |
|
190 strlen for null-terminated 16-bit strings |
|
191 */ |
|
192 inline TInt CExpat::StringLen(TUint16* aStart) |
|
193 { |
|
194 TUint16* p = aStart; |
|
195 while (*p++) |
|
196 ; |
|
197 return p-1-aStart; |
|
198 } |
|
199 |
|
200 #endif // CEXPAT_H |