1 /* |
|
2 * Licensed to the Apache Software Foundation (ASF) under one or more |
|
3 * contributor license agreements. See the NOTICE file distributed with |
|
4 * this work for additional information regarding copyright ownership. |
|
5 * The ASF licenses this file to You under the Apache License, Version 2.0 |
|
6 * (the "License"); you may not use this file except in compliance with |
|
7 * the License. You may obtain a copy of the License at |
|
8 * |
|
9 * http://www.apache.org/licenses/LICENSE-2.0 |
|
10 * |
|
11 * Unless required by applicable law or agreed to in writing, software |
|
12 * distributed under the License is distributed on an "AS IS" BASIS, |
|
13 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. |
|
14 * See the License for the specific language governing permissions and |
|
15 * limitations under the License. |
|
16 */ |
|
17 |
|
18 /* |
|
19 * $Id: ReaderMgr.hpp 568078 2007-08-21 11:43:25Z amassari $ |
|
20 */ |
|
21 |
|
22 #if !defined(READERMGR_HPP) |
|
23 #define READERMGR_HPP |
|
24 |
|
25 #include <xercesc/internal/XMLReader.hpp> |
|
26 #include <xercesc/util/PlatformUtils.hpp> |
|
27 #include <xercesc/util/RefStackOf.hpp> |
|
28 #include <xercesc/sax/Locator.hpp> |
|
29 #include <xercesc/framework/XMLBuffer.hpp> |
|
30 |
|
31 XERCES_CPP_NAMESPACE_BEGIN |
|
32 |
|
33 class XMLEntityDecl; |
|
34 class XMLEntityHandler; |
|
35 class XMLDocumentHandler; |
|
36 class XMLScanner; |
|
37 |
|
38 |
|
39 // --------------------------------------------------------------------------- |
|
40 // This class is used by the scanner. The scanner must deal with expansion |
|
41 // of entities, some of which are totally different files (external parsed |
|
42 // entities.) It does so by pushing readers onto a stack. The top reader is |
|
43 // the one it wants to read out of, but that one must be popped when it is |
|
44 // empty. To keep that logic from being all over the place, the scanner |
|
45 // talks to the reader manager, which handles the stack and popping off |
|
46 // used up readers. |
|
47 // --------------------------------------------------------------------------- |
|
48 class XMLPARSER_EXPORT ReaderMgr : public XMemory |
|
49 , public Locator |
|
50 { |
|
51 public : |
|
52 // ----------------------------------------------------------------------- |
|
53 // Class specific types |
|
54 // ----------------------------------------------------------------------- |
|
55 struct LastExtEntityInfo : public XMemory |
|
56 { |
|
57 const XMLCh* systemId; |
|
58 const XMLCh* publicId; |
|
59 XMLSSize_t lineNumber; |
|
60 XMLSSize_t colNumber; |
|
61 }; |
|
62 |
|
63 |
|
64 // ----------------------------------------------------------------------- |
|
65 // Constructors and Destructor |
|
66 // ----------------------------------------------------------------------- |
|
67 ReaderMgr(MemoryManager* const manager = XMLPlatformUtils::fgMemoryManager); |
|
68 ~ReaderMgr(); |
|
69 |
|
70 |
|
71 // ----------------------------------------------------------------------- |
|
72 // Convenience scanning methods |
|
73 // |
|
74 // This are all convenience methods that work in terms of the core |
|
75 // character spooling methods. |
|
76 // ----------------------------------------------------------------------- |
|
77 bool atEOF() const; |
|
78 bool getName(XMLBuffer& toFill); |
|
79 bool getQName(XMLBuffer& toFill, int* colonPosition); |
|
80 bool getNameToken(XMLBuffer& toFill); |
|
81 XMLCh getNextChar(); |
|
82 bool getNextCharIfNot(const XMLCh chNotToGet, XMLCh& chGotten); |
|
83 void movePlainContentChars(XMLBuffer &dest); |
|
84 void getSpaces(XMLBuffer& toFill); |
|
85 void getUpToCharOrWS(XMLBuffer& toFill, const XMLCh toCheck); |
|
86 bool isEmpty() const; |
|
87 bool lookingAtChar(const XMLCh toCheck); |
|
88 bool lookingAtSpace(); |
|
89 XMLCh peekNextChar(); |
|
90 bool skipIfQuote(XMLCh& chGotten); |
|
91 void skipPastChar(const XMLCh toSkip); |
|
92 bool skipPastSpaces(bool inDecl = false); |
|
93 void skipToChar(const XMLCh toSkipTo); |
|
94 bool skippedChar(const XMLCh toSkip); |
|
95 bool skippedSpace(); |
|
96 bool skippedString(const XMLCh* const toSkip); |
|
97 void skipQuotedString(const XMLCh quoteCh); |
|
98 XMLCh skipUntilIn(const XMLCh* const listToSkip); |
|
99 XMLCh skipUntilInOrWS(const XMLCh* const listToSkip); |
|
100 bool peekString(const XMLCh* const toPeek); |
|
101 |
|
102 |
|
103 // ----------------------------------------------------------------------- |
|
104 // Control methods |
|
105 // ----------------------------------------------------------------------- |
|
106 void cleanStackBackTo(const unsigned int readerNum); |
|
107 XMLReader* createReader |
|
108 ( |
|
109 const InputSource& src |
|
110 , const bool xmlDecl |
|
111 , const XMLReader::RefFrom refFrom |
|
112 , const XMLReader::Types type |
|
113 , const XMLReader::Sources source |
|
114 , const bool calcSrsOfs = true |
|
115 ); |
|
116 XMLReader* createReader |
|
117 ( |
|
118 const XMLCh* const sysId |
|
119 , const XMLCh* const pubId |
|
120 , const bool xmlDecl |
|
121 , const XMLReader::RefFrom refFrom |
|
122 , const XMLReader::Types type |
|
123 , const XMLReader::Sources source |
|
124 , InputSource*& srcToFill |
|
125 , const bool calcSrcOfs = true |
|
126 , const bool disableDefaultEntityResolution = false |
|
127 ); |
|
128 XMLReader* createReader |
|
129 ( |
|
130 const XMLCh* const baseURI |
|
131 , const XMLCh* const sysId |
|
132 , const XMLCh* const pubId |
|
133 , const bool xmlDecl |
|
134 , const XMLReader::RefFrom refFrom |
|
135 , const XMLReader::Types type |
|
136 , const XMLReader::Sources source |
|
137 , InputSource*& srcToFill |
|
138 , const bool calcSrcOfs = true |
|
139 , const bool disableDefaultEntityResolution = false |
|
140 ); |
|
141 XMLReader* createIntEntReader |
|
142 ( |
|
143 const XMLCh* const sysId |
|
144 , const XMLReader::RefFrom refFrom |
|
145 , const XMLReader::Types type |
|
146 , const XMLCh* const dataBuf |
|
147 , const unsigned int dataLen |
|
148 , const bool copyBuf |
|
149 , const bool calcSrcOfs = true |
|
150 ); |
|
151 bool isScanningPERefOutOfLiteral() const; |
|
152 bool pushReader |
|
153 ( |
|
154 XMLReader* const reader |
|
155 , XMLEntityDecl* const entity |
|
156 ); |
|
157 void reset(); |
|
158 |
|
159 |
|
160 // ----------------------------------------------------------------------- |
|
161 // Getter methods |
|
162 // ----------------------------------------------------------------------- |
|
163 const XMLCh* getCurrentEncodingStr() const; |
|
164 const XMLEntityDecl* getCurrentEntity() const; |
|
165 XMLEntityDecl* getCurrentEntity(); |
|
166 const XMLReader* getCurrentReader() const; |
|
167 XMLReader* getCurrentReader(); |
|
168 unsigned int getCurrentReaderNum() const; |
|
169 unsigned int getReaderDepth() const; |
|
170 void getLastExtEntityInfo(LastExtEntityInfo& lastInfo) const; |
|
171 unsigned int getSrcOffset() const; |
|
172 bool getThrowEOE() const; |
|
173 |
|
174 |
|
175 // ----------------------------------------------------------------------- |
|
176 // Setter methods |
|
177 // ----------------------------------------------------------------------- |
|
178 void setEntityHandler(XMLEntityHandler* const newHandler); |
|
179 void setThrowEOE(const bool newValue); |
|
180 void setXMLVersion(const XMLReader::XMLVersion version); |
|
181 void setStandardUriConformant(const bool newValue); |
|
182 |
|
183 // ----------------------------------------------------------------------- |
|
184 // Implement the SAX Locator interface |
|
185 // ----------------------------------------------------------------------- |
|
186 virtual const XMLCh* getPublicId() const; |
|
187 virtual const XMLCh* getSystemId() const; |
|
188 virtual XMLSSize_t getLineNumber() const; |
|
189 virtual XMLSSize_t getColumnNumber() const; |
|
190 |
|
191 |
|
192 private : |
|
193 // ----------------------------------------------------------------------- |
|
194 // Private helper methods |
|
195 // ----------------------------------------------------------------------- |
|
196 const XMLReader* getLastExtEntity(const XMLEntityDecl*& itsEntity) const; |
|
197 bool popReader(); |
|
198 |
|
199 // ----------------------------------------------------------------------- |
|
200 // Unimplemented constructors and operators |
|
201 // ----------------------------------------------------------------------- |
|
202 ReaderMgr(const ReaderMgr&); |
|
203 ReaderMgr& operator=(const ReaderMgr&); |
|
204 |
|
205 // ----------------------------------------------------------------------- |
|
206 // Private data members |
|
207 // |
|
208 // fCurEntity |
|
209 // This is the current top of stack entity. We pull it off the stack |
|
210 // and store it here for efficiency. |
|
211 // |
|
212 // fCurReader |
|
213 // This is the current top of stack reader. We pull it off the |
|
214 // stack and store it here for efficiency. |
|
215 // |
|
216 // fEntityHandler |
|
217 // This is the installed entity handler. Its installed via the |
|
218 // scanner but he passes it on to us since we need it the most, in |
|
219 // process of creating external entity readers. |
|
220 // |
|
221 // fEntityStack |
|
222 // We need to keep up with which of the pushed readers are pushed |
|
223 // entity values that are being spooled. This is done to avoid the |
|
224 // problem of recursive definitions. This stack consists of refs to |
|
225 // EntityDecl objects for the pushed entities. |
|
226 // |
|
227 // fNextReaderNum |
|
228 // This is the reader serial number value. Each new reader that is |
|
229 // created from this reader is given a successive number. This lets |
|
230 // us catch things like partial markup errors and such. |
|
231 // |
|
232 // fReaderStack |
|
233 // This is the stack of reader references. We own all the readers |
|
234 // and destroy them when they are used up. |
|
235 // |
|
236 // fThrowEOE |
|
237 // This flag controls whether we throw an exception when we hit an |
|
238 // end of entity. The scanner doesn't really need to know about ends |
|
239 // of entities in the int/ext subsets, so it will turn this flag off |
|
240 // until it gets into the content usually. |
|
241 // |
|
242 // fXMLVersion |
|
243 // Enum to indicate if each Reader should be created as XML 1.1 or |
|
244 // XML 1.0 conformant |
|
245 // |
|
246 // fStandardUriConformant |
|
247 // This flag controls whether we force conformant URI |
|
248 // ----------------------------------------------------------------------- |
|
249 XMLEntityDecl* fCurEntity; |
|
250 XMLReader* fCurReader; |
|
251 XMLEntityHandler* fEntityHandler; |
|
252 RefStackOf<XMLEntityDecl>* fEntityStack; |
|
253 unsigned int fNextReaderNum; |
|
254 RefStackOf<XMLReader>* fReaderStack; |
|
255 bool fThrowEOE; |
|
256 XMLReader::XMLVersion fXMLVersion; |
|
257 bool fStandardUriConformant; |
|
258 MemoryManager* fMemoryManager; |
|
259 }; |
|
260 |
|
261 |
|
262 |
|
263 // --------------------------------------------------------------------------- |
|
264 // ReaderMgr: Inlined methods |
|
265 // |
|
266 // NOTE: We cannot put these in alphabetical and type order as we usually |
|
267 // do because some of the compilers we have to support are too stupid to |
|
268 // understand out of order inlines! |
|
269 // --------------------------------------------------------------------------- |
|
270 inline unsigned int ReaderMgr::getCurrentReaderNum() const |
|
271 { |
|
272 return fCurReader->getReaderNum(); |
|
273 } |
|
274 |
|
275 inline const XMLReader* ReaderMgr::getCurrentReader() const |
|
276 { |
|
277 return fCurReader; |
|
278 } |
|
279 |
|
280 inline XMLReader* ReaderMgr::getCurrentReader() |
|
281 { |
|
282 return fCurReader; |
|
283 } |
|
284 |
|
285 inline bool ReaderMgr::getName(XMLBuffer& toFill) |
|
286 { |
|
287 toFill.reset(); |
|
288 return fCurReader->getName(toFill, false); |
|
289 } |
|
290 |
|
291 inline bool ReaderMgr::getQName(XMLBuffer& toFill, int *colonPosition) |
|
292 { |
|
293 toFill.reset(); |
|
294 return fCurReader->getQName(toFill, colonPosition); |
|
295 } |
|
296 |
|
297 inline bool ReaderMgr::getNameToken(XMLBuffer& toFill) |
|
298 { |
|
299 toFill.reset(); |
|
300 return fCurReader->getName(toFill, true); |
|
301 } |
|
302 |
|
303 inline bool ReaderMgr::getNextCharIfNot(const XMLCh chNotToGet, XMLCh& chGotten) |
|
304 { |
|
305 return fCurReader->getNextCharIfNot(chNotToGet, chGotten); |
|
306 } |
|
307 |
|
308 inline void ReaderMgr::movePlainContentChars(XMLBuffer &dest) |
|
309 { |
|
310 fCurReader->movePlainContentChars(dest); |
|
311 } |
|
312 |
|
313 inline bool ReaderMgr::getThrowEOE() const |
|
314 { |
|
315 return fThrowEOE; |
|
316 } |
|
317 |
|
318 inline unsigned int ReaderMgr::getSrcOffset() const |
|
319 { |
|
320 return fCurReader? fCurReader->getSrcOffset() : 0; |
|
321 } |
|
322 |
|
323 inline bool ReaderMgr::lookingAtChar(const XMLCh chToCheck) |
|
324 { |
|
325 return (chToCheck == peekNextChar()); |
|
326 } |
|
327 |
|
328 inline bool ReaderMgr::lookingAtSpace() |
|
329 { |
|
330 XMLCh c = peekNextChar(); |
|
331 return fCurReader->isWhitespace(c); |
|
332 } |
|
333 |
|
334 inline void ReaderMgr::setThrowEOE(const bool newValue) |
|
335 { |
|
336 fThrowEOE = newValue; |
|
337 } |
|
338 |
|
339 inline void ReaderMgr::setStandardUriConformant(const bool newValue) |
|
340 { |
|
341 fStandardUriConformant = newValue; |
|
342 } |
|
343 |
|
344 inline bool ReaderMgr::skippedString(const XMLCh* const toSkip) |
|
345 { |
|
346 return fCurReader->skippedString(toSkip); |
|
347 } |
|
348 |
|
349 inline void ReaderMgr::skipToChar(const XMLCh toSkipTo) |
|
350 { |
|
351 XMLCh nextCh = 0; |
|
352 do |
|
353 { |
|
354 // Get chars until we find the one to skip |
|
355 nextCh = getNextChar(); |
|
356 } |
|
357 // Break out at end of input or the char to skip |
|
358 while((nextCh != toSkipTo) && nextCh!=0); |
|
359 } |
|
360 |
|
361 inline void ReaderMgr::skipPastChar(const XMLCh toSkipPast) |
|
362 { |
|
363 XMLCh nextCh = 0; |
|
364 do |
|
365 { |
|
366 // Get chars until we find the one to skip |
|
367 nextCh = getNextChar(); |
|
368 } |
|
369 while((nextCh != toSkipPast) && nextCh!=0); |
|
370 } |
|
371 |
|
372 inline bool ReaderMgr::peekString(const XMLCh* const toPeek) |
|
373 { |
|
374 return fCurReader->peekString(toPeek); |
|
375 } |
|
376 |
|
377 inline void ReaderMgr::setEntityHandler(XMLEntityHandler* const newHandler) |
|
378 { |
|
379 fEntityHandler = newHandler; |
|
380 } |
|
381 |
|
382 inline void ReaderMgr::setXMLVersion(const XMLReader::XMLVersion version) |
|
383 { |
|
384 fXMLVersion = version; |
|
385 fCurReader->setXMLVersion(version); |
|
386 } |
|
387 |
|
388 // |
|
389 // This is a simple class to temporarily change the 'throw at end of entity' |
|
390 // flag of the reader manager. There are some places where we need to |
|
391 // turn this on and off on a scoped basis. |
|
392 // |
|
393 class XMLPARSER_EXPORT ThrowEOEJanitor |
|
394 { |
|
395 public : |
|
396 // ----------------------------------------------------------------------- |
|
397 // Constructors and destructor |
|
398 // ----------------------------------------------------------------------- |
|
399 ThrowEOEJanitor(ReaderMgr* mgrTarget, const bool newValue) : |
|
400 |
|
401 fOld(mgrTarget->getThrowEOE()) |
|
402 , fMgr(mgrTarget) |
|
403 { |
|
404 mgrTarget->setThrowEOE(newValue); |
|
405 } |
|
406 |
|
407 ~ThrowEOEJanitor() |
|
408 { |
|
409 fMgr->setThrowEOE(fOld); |
|
410 }; |
|
411 |
|
412 private : |
|
413 // ----------------------------------------------------------------------- |
|
414 // Unimplemented constructors and operators |
|
415 // ----------------------------------------------------------------------- |
|
416 ThrowEOEJanitor(const ThrowEOEJanitor&); |
|
417 ThrowEOEJanitor& operator=(const ThrowEOEJanitor&); |
|
418 |
|
419 // ----------------------------------------------------------------------- |
|
420 // Private data members |
|
421 // |
|
422 // fOld |
|
423 // The previous value of the flag, which we replaced during ctor, |
|
424 // and will replace during dtor. |
|
425 // |
|
426 // fMgr |
|
427 // A pointer to the reader manager we are going to set/reset the |
|
428 // flag on. |
|
429 // ----------------------------------------------------------------------- |
|
430 bool fOld; |
|
431 ReaderMgr* fMgr; |
|
432 }; |
|
433 |
|
434 XERCES_CPP_NAMESPACE_END |
|
435 |
|
436 #endif |
|