[2674] | 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 |
---|