source: icXML/icXML-devel/src/icxercesc/internal/XMLReader.hpp @ 2807

Last change on this file since 2807 was 2807, checked in by cameron, 6 years ago

Fixes default attribute+namespace resolution; hashing

File size: 31.3 KB
Line 
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: XMLReader.hpp 833045 2009-11-05 13:21:27Z borisk $
20 */
21
22#if !defined(XERCESC_INCLUDE_GUARD_XMLREADER_HPP)
23#define XERCESC_INCLUDE_GUARD_XMLREADER_HPP
24
25#include <xercesc/util/XMLChar.hpp>
26#include <xercesc/framework/XMLErrorCodes.hpp>
27#include <icxercesc/framework/XMLRecognizer.hpp>
28#include <icxercesc/framework/XMLBuffer.hpp>
29#include <xercesc/util/TranscodingException.hpp>
30#include <icxercesc/util/TransService.hpp>
31#include <icxercesc/framework/XMLElementDecl.hpp>
32#include <xercesc/util/BinInputStream.hpp>
33#include <icxercesc/util/TransService.hpp>
34#include <icxmlc/XMLConfig.hpp>
35#include <icxmlc/Array.hpp>
36
37#include <iostream>
38
39// WARNING: callgrind requires that valgrind is installed on your system. This include is not
40// necessary to use callgrind.
41#ifdef ENABLE_CALLGRIND_PROFILING
42#include <valgrind/callgrind.h>
43#else
44#define CALLGRIND_START_INSTRUMENTATION
45#define CALLGRIND_STOP_INSTRUMENTATION
46#define CALLGRIND_DUMP_STATS
47#endif
48
49XERCES_CPP_NAMESPACE_BEGIN
50
51class ReaderMgr;
52class InputSource;
53class XMLParser;
54template <typename XMLScannerType> class XMLParserImpl;
55
56// -----------------------------------------------------------------------------------------------
57
58#if !defined(XERCESC_INCLUDE_GUARD_BININPUTSTREAM_HPP)
59class BinInputStream;
60#endif
61#if !defined(XERCESC_INCLUDE_GUARD_XMLSCANNER_HPP)
62class XMLScanner;
63#endif
64
65// ---------------------------------------------------------------------------
66//  Instances of this class are used to manage the content of entities. The
67//  scanner maintains a stack of these, one for each entity (this means entity
68//  in the sense of any parsed file or internal entity) currently being
69//  scanned. This class, given a binary input stream will handle reading in
70//  the data and decoding it from its external decoding into the internal
71//  Unicode format. Once internallized, this class provides the access
72//  methods to read in the data in various ways, maintains line and column
73//  information, and provides high performance character attribute checking
74//  methods.
75//
76//  This is NOT to be derived from.
77//
78// ---------------------------------------------------------------------------
79
80class XMLPARSER_EXPORT XMLReader : public XMemory
81{
82        friend class ReaderMgr;
83public:
84        // -----------------------------------------------------------------------
85        //  Public types
86        // -----------------------------------------------------------------------
87        enum Types
88        {
89                Type_PE
90                , Type_General
91        };
92
93        enum Sources
94        {
95                Source_Internal
96                , Source_External
97        };
98
99        enum RefFrom
100        {
101                RefFrom_Literal
102                , RefFrom_NonLiteral
103        };
104
105    enum XMLVersion
106    {
107        XMLV1_0
108        , XMLV1_1
109        , XMLV_Unknown
110    };
111
112        // -----------------------------------------------------------------------
113        //  Public, query methods
114        // -----------------------------------------------------------------------
115        bool isAllSpaces
116        (
117                const   XMLCh* const    toCheck
118                , const XMLSize_t       count
119        ) const;
120
121        bool containsWhiteSpace
122        (
123                const   XMLCh* const    toCheck
124                , const XMLSize_t       count
125        ) const;
126
127        bool isXMLLetter(const XMLCh toCheck) const;
128        bool isFirstNameChar(const XMLCh toCheck) const;
129        bool isNameChar(const XMLCh toCheck) const;
130        bool isPlainContentChar(const XMLCh toCheck) const;
131        bool isSpecialStartTagChar(const XMLCh toCheck) const;
132        bool isXMLChar(const XMLCh toCheck) const;
133        bool isWhitespace(const XMLCh toCheck) const;
134        bool isControlChar(const XMLCh toCheck) const;
135        bool isPublicIdChar(const XMLCh toCheck) const;
136        bool isFirstNCNameChar(const XMLCh toCheck) const;
137        bool isNCNameChar(const XMLCh toCheck) const;
138
139        // -----------------------------------------------------------------------
140        //  Constructors and Destructor
141        // -----------------------------------------------------------------------
142        XMLReader
143        (
144                const   XMLCh* const          pubId
145                , const XMLCh* const          sysId
146                ,       BinInputStream* const streamToAdopt
147                , const RefFrom               from
148                , const Types                 type
149                , const Sources               source
150                , const bool                  throwAtEnd
151                , const bool                  calculateSrcOfs
152                ,       XMLSize_t             lowWaterMark
153                , const XMLVersion            xmlVersion
154                ,       MemoryManager* const  manager
155        );
156
157        XMLReader
158        (
159                const   XMLCh* const          pubId
160                , const XMLCh* const          sysId
161                ,       BinInputStream* const streamToAdopt
162                , const XMLCh* const          encodingStr
163                , const RefFrom               from
164                , const Types                 type
165                , const Sources               source
166                , const bool                  throwAtEnd
167                , const bool                  calculateSrcOfs
168                ,       XMLSize_t             lowWaterMark
169                , const XMLVersion            xmlVersion
170                ,       MemoryManager* const  manager
171        );
172
173        XMLReader
174        (
175                const   XMLCh* const          pubId
176                , const XMLCh* const          sysId
177                ,       BinInputStream* const streamToAdopt
178                , XMLRecognizer::Encodings    encodingEnum
179                , const RefFrom               from
180                , const Types                 type
181                , const Sources               source
182                , const bool                  throwAtEnd
183                , const bool                  calculateSrcOfs
184                ,       XMLSize_t             lowWaterMark
185                , const XMLVersion            xmlVersion
186                ,       MemoryManager* const  manager
187        );
188
189        ~XMLReader();
190
191
192        // -----------------------------------------------------------------------
193        //  Character buffer management methods
194        // -----------------------------------------------------------------------
195        XMLSize_t charsLeftInBuffer() const;
196        bool refreshCharBuffer();
197
198        // -----------------------------------------------------------------------
199        //  Scanning methods
200        // -----------------------------------------------------------------------
201        bool getName(XMLBuffer& toFill, const bool token);
202        bool getQName(XMLBuffer& toFill, int* colonPosition);
203        bool getNCName(XMLBuffer& toFill);
204        bool getNextChar(XMLCh& chGotten);
205        bool getNextCharIfNot(const XMLCh chNotToGet, XMLCh& chGotten);
206        void movePlainContentChars(XMLBuffer &dest);
207        bool getSpaces(XMLBuffer& toFill);
208        bool getUpToCharOrWS(XMLBuffer& toFill, const XMLCh toCheck);
209        bool peekNextChar(XMLCh& chGotten);
210        bool skipIfQuote(XMLCh& chGotten);
211        bool skipSpaces(bool& skippedSomething, bool inDecl = false);
212        bool skippedChar(const XMLCh toSkip);
213        bool skippedSpace();
214        bool skippedString(const XMLCh* const toSkip);
215        bool skippedStringLong(const XMLCh* toSkip);
216        bool peekString(const XMLCh* const toPeek);
217
218
219        // -----------------------------------------------------------------------
220        //  Getter methods
221        // -----------------------------------------------------------------------
222        XMLFileLoc getColumnNumber() const;
223        const XMLCh* getEncodingStr() const;
224        XMLFileLoc getLineNumber() const;
225        bool getNoMoreFlag() const;
226        const XMLCh* getPublicId() const;
227        XMLSize_t getReaderNum() const;
228        RefFrom getRefFrom() const;
229        Sources getSource() const;
230        XMLFilePos getSrcOffset() const;
231        const XMLCh* getSystemId() const;
232        bool getThrowAtEnd() const;
233        Types getType() const;
234
235
236        // -----------------------------------------------------------------------
237        //  Setter methods
238        // -----------------------------------------------------------------------
239        bool setEncoding
240        (
241                const   XMLCh* const    newEncoding
242        );
243        void setReaderNum(const XMLSize_t newNum);
244        void setThrowAtEnd(const bool newValue);
245        void setXMLVersion(const XMLVersion version);
246
247        // ---------------------------------------------------------------------------
248        //  Class Constants
249        //
250        //  kCharBufSize
251        //      The size of the character spool buffer that we use. Its not terribly
252        //      large because its just getting filled with data from a raw byte
253        //      buffer as we go along. We don't want to decode all the text at
254        //      once before we find out that there is an error.
255        //
256        //      NOTE: This is a size in characters, not bytes.
257        //
258        //  kRawBufSize
259        //      The size of the raw buffer from which raw bytes are spooled out
260        //      as we transcode chunks of data. As it is emptied, it is filled back
261        //      in again from the source stream.
262        // ---------------------------------------------------------------------------
263        enum Constants
264        {
265                kCharBufSize        = 128
266                , kRawBufSize       = BUFFER_BLOCKS * BLOCK_SIZE
267        };
268
269        // -----------------------------------------------------------------------
270        // PARABIX SCANNING FUNCTIONS
271        // -----------------------------------------------------------------------
272
273        template <class XMLScannerType>
274        bool scanDocument( XMLScannerType * const scanner );
275
276        template <class XMLScannerType>
277        XMLParserImpl<XMLScannerType> * scanFirst(XMLScannerType * const scanner);
278
279        template <class XMLScannerType>
280        bool scanNext(XMLParserImpl<XMLScannerType> & parser);
281
282        IDISA_ALWAYS_INLINE
283        void refreshRawBuffer(const XMLSize_t offset);
284
285        IDISA_ALWAYS_INLINE
286        void refreshRawBuffer(const XMLSize_t from, const XMLSize_t to);
287
288        void getCurrentLineColumn(XMLFileLoc & line, XMLFileLoc & col) const;
289
290private:
291        // -----------------------------------------------------------------------
292        //  Unimplemented constructors and operators
293        // -----------------------------------------------------------------------
294        XMLReader(const XMLReader&);
295        XMLReader& operator=(const XMLReader&);
296
297        // -----------------------------------------------------------------------
298        //  Private helper methods
299        // -----------------------------------------------------------------------
300
301        void doInitCharSizeChecks();
302
303        void doInitDecode();
304
305        bool constructTranscoder();
306
307        bool constructCharacterSetAdapter();
308
309        XMLByte getNextRawByte
310        (
311                const   bool            eoiOk
312        );
313
314        void setTranscoder
315        (
316                const   XMLCh* const    newEncoding
317        );
318
319        XMLSize_t xcodeMoreChars
320        (
321                                XMLCh* const            bufToFill
322                ,       unsigned char* const    charSizes
323                , const XMLSize_t               maxChars
324        );
325
326        void handleEOL
327        (
328                          XMLCh&   curCh
329                        , bool     inDecl = false
330        );
331
332        void refreshRawBuffer();
333
334        void checkForSwapped();
335
336        // -----------------------------------------------------------------------
337        //  Data members
338        //
339        //  fCharIndex
340        //      The index into the character buffer. When this hits fCharsAvail
341        //      then its time to refill.
342        //
343        //  fCharBuf
344        //      A buffer that the reader manager fills up with transcoded
345        //      characters a small amount at a time.
346        //
347        //  fCharsAvail
348        //      The characters currently available in the character buffer.
349        //
350        //  fCharSizeBuf
351        //      This buffer is an array that contains the number of source chars
352        //      eaten to create each char in the fCharBuf buffer. So the entry
353        //      fCharSizeBuf[x] is the number of source chars that were eaten
354        //      to make the internalized char fCharBuf[x]. This only contains
355        //      useful data if fSrcOfsSupported is true.
356        //
357        //  fCharOfsBuf
358        //      This buffer is an array that contains the offset in the
359        //      fRawByteBuf buffer of each char in the fCharBuf buffer. It
360        //      only contains useful data if fSrcOfsSupported is true.
361        //
362        //  fCurCol
363        //  fCurLine
364        //      The current line and column that we are in within this reader's
365        //      text.
366        //
367        //  fEncoding
368        //      This is the rough encoding setting. This enum is set during
369        //      construction and just tells us the rough family of encoding that
370        //      we are doing.
371        //
372        //  fEncodingStr
373        //      This is the name of the encoding we are using. It will be
374        //      provisionally set during construction, from the auto-sensed
375        //      encoding. But it might be overridden when the XMLDecl is finally
376        //      seen by the scanner. It can also be forced to a particular
377        //      encoding, in which case fForcedEncoding is set.
378        //
379        //  fForcedEncoding
380        //      If the encoding if forced then this is set and all other
381        //      information will be ignored. This encoding will be taken as
382        //      gospel. This is done by calling an alternate constructor.
383        //
384        //  fNoMore
385        //      This is set when the source text is exhausted. It lets us know
386        //      quickly that no more text is available.
387        //
388        //  fRawBufIndex
389        //      The current index into the raw byte buffer. When its equal to
390        //      fRawBytesAvail then we need to read another buffer.
391        //
392        //  fRawByteBuf
393        //      This is the raw byte buffer that is used to spool out bytes
394        //      from into the fCharBuf buffer, as we transcode in blocks.
395        //
396        //  fRawBytesAvail
397        //      The number of bytes currently available in the raw buffer. This
398        //      helps deal with the last buffer's worth, which will usually not
399        //      be a full one.
400        //
401        //  fLowWaterMark
402        //      The low water mark for the raw byte buffer.
403        //
404        //
405        //  fReaderNum
406        //      Each reader from a particular reader manager (which means from a
407        //      particular document) is given a unique number. The reader manager
408        //      sets these numbers. They are used to catch things like partial
409        //      markup errors.
410        //
411        //  fRefFrom
412        //      This flag is provided in the ctor, and tells us if we represent
413        //      some entity being expanded inside a literal. Sometimes things
414        //      happen differently inside and outside literals.
415        //
416        //  fPublicId
417        //  fSystemId
418        //      These are the system and public ids of the source that this
419        //      reader is reading.
420        //
421        //  fSentTrailingSpace
422        //      If we are a PE entity being read and we not referenced from a
423        //      literal, then a leading and trailing space must be faked into the
424        //      data. This lets us know we've done the trailing space already (so
425        //      we don't just keep doing it again and again.)
426        //
427        //  fSource
428        //      Indicates whether the content this reader is spooling as already
429        //      been internalized. This will prevent multiple processing of
430        //      whitespace when an already internalized entity is being spooled
431        //      out.
432        //
433        //  fSpareChar
434        //      Some encodings can create two chars in an atomic way, e.g.
435        //      surrogate pairs. We might not be able to store both, so we store
436        //      it here until the next buffer transcoding operation.
437        //
438        //  fSrcOfsBase
439        //      This is the base offset within the source of this entity. Values
440        //      in the curent fCharSizeBuf array are relative to this value.
441        //
442        //  fSrcOfsSupported
443        //      This flag is set to indicate whether source byte offset info
444        //      is supported. For intrinsic encodings, its always set since we
445        //      can always support it. For transcoder based encodings, we ask
446        //      the transcoder if it supports it or not.
447        //
448        //  fStream
449        //      This is the input stream that provides the data for the reader.
450        //      Its always treated as a raw byte stream. The derived class will
451        //      ask for buffers of text from it and will handle making some
452        //      sense of it.
453        //
454        //  fSwapped
455        //      If the encoding is one of the ones we do intrinsically, and its
456        //      in a different byte order from our native order, then this is
457        //      set to remind us to byte swap it during transcoding.
458        //
459        //  fThrowAtEnd
460        //      Indicates whether the reader manager should throw an end of entity
461        //      exception at the end of this reader instance. This is usually
462        //      set for top level external entity references. It overrides the
463        //      reader manager's global flag that controls throwing at the end
464        //      of entities. Defaults to false.
465        //
466        //  fTranscoder
467        //      If the encoding is not one that we handle intrinsically, then
468        //      we use an an external transcoder to do it. This class is an
469        //      abstraction that allows us to use pluggable external transcoding
470        //      services (via XMLTransService in util.)
471        //
472        //  fType
473        //      Indicates whether this reader represents a PE or not. If this
474        //      flag is true and the fInLiteral flag is false, then we will put
475        //      out an extra space at the end.
476        //
477        //  fgCharCharsTable;
478        //      Pointer to XMLChar table, depends on XML version
479        //
480        //  fNEL
481        //      Boolean indicates if NEL and LSEP should be recognized as NEL
482        //
483        //  fXMLVersion
484        //      Enum to indicate if this Reader is conforming to XML 1.0 or XML 1.1
485        // -----------------------------------------------------------------------
486
487        XMLSize_t                   fCharIndex;
488        XMLCh                       fCharBuf[kCharBufSize];
489        XMLSize_t                   fCharsAvail;
490        unsigned char               fCharSizeBuf[kCharBufSize + sizeof(BytePack)];
491        XMLFileLoc                  fCurCol;
492        XMLFileLoc                  fCurLine;
493        XMLRecognizer::Encodings    fEncoding;
494        const XMLCh *               fEncodingStr;
495        bool                        fForcedEncoding;
496        bool                        fNoMore;
497        XMLCh*                      fPublicId;
498        XMLSize_t                   fRawBufIndex;
499        XMLByte                     fRawByteBuf[kRawBufSize + sizeof(BytePack)];
500        XMLSize_t                   fRawBytesAvail;
501        XMLSize_t                   fRawBytesRead;
502        XMLSize_t                   fReaderNum;
503        RefFrom                     fRefFrom;
504        bool                        fSentTrailingSpace;
505        Sources                     fSource;
506        XMLFilePos                  fSrcOfsBase;
507        XMLCh*                      fSystemId;
508        BinInputStream*             fStream;
509        bool                        fSwapped;
510        bool                        fThrowAtEnd;
511        XMLTranscoder*              fTranscoder;
512        XMLCharacterSetAdapter*     fCharacterSetAdapter;
513        Types                       fType;
514        XMLByte*                    fgCharCharsTable;
515        bool                        fNEL;
516        XMLVersion                  fXMLVersion;
517        MemoryManager*              fMemoryManager;
518        // the internal parser is stored as void to bypass the fact the parser is templated
519        XMLParser*                  fParser;
520};
521
522// ---------------------------------------------------------------------------
523//  XMLReader: Public, query methods
524// ---------------------------------------------------------------------------
525inline bool XMLReader::isNameChar(const XMLCh toCheck) const
526{
527        return ((fgCharCharsTable[toCheck] & gNameCharMask) != 0);
528}
529
530inline bool XMLReader::isNCNameChar(const XMLCh toCheck) const
531{
532        return ((fgCharCharsTable[toCheck] & gNCNameCharMask) != 0);
533}
534
535inline bool XMLReader::isPlainContentChar(const XMLCh toCheck) const
536{
537        return ((fgCharCharsTable[toCheck] & gPlainContentCharMask) != 0);
538}
539
540
541inline bool XMLReader::isFirstNameChar(const XMLCh toCheck) const
542{
543        return ((fgCharCharsTable[toCheck] & gFirstNameCharMask) != 0);
544}
545
546inline bool XMLReader::isFirstNCNameChar(const XMLCh toCheck) const
547{
548        return (((fgCharCharsTable[toCheck] & gFirstNameCharMask) != 0)
549                        && (toCheck != chColon));
550}
551
552inline bool XMLReader::isSpecialStartTagChar(const XMLCh toCheck) const
553{
554        return ((fgCharCharsTable[toCheck] & gSpecialStartTagCharMask) != 0);
555}
556
557inline bool XMLReader::isXMLChar(const XMLCh toCheck) const
558{
559        return ((fgCharCharsTable[toCheck] & gXMLCharMask) != 0);
560}
561
562inline bool XMLReader::isXMLLetter(const XMLCh toCheck) const
563{
564        return (((fgCharCharsTable[toCheck] & gFirstNameCharMask) != 0)
565                        && (toCheck != chColon) && (toCheck != chUnderscore));
566}
567
568inline bool XMLReader::isWhitespace(const XMLCh toCheck) const
569{
570        return ((fgCharCharsTable[toCheck] & gWhitespaceCharMask) != 0);
571}
572
573inline bool XMLReader::isControlChar(const XMLCh toCheck) const
574{
575        return ((fgCharCharsTable[toCheck] & gControlCharMask) != 0);
576}
577
578// ---------------------------------------------------------------------------
579//  XMLReader: Buffer management methods
580// ---------------------------------------------------------------------------
581inline XMLSize_t XMLReader::charsLeftInBuffer() const
582{
583        return fCharsAvail - fCharIndex;
584}
585
586// ---------------------------------------------------------------------------
587//  XMLReader: Getter methods
588// ---------------------------------------------------------------------------
589inline XMLFileLoc XMLReader::getColumnNumber() const
590{
591    return fCurCol;
592}
593
594inline const XMLCh* XMLReader::getEncodingStr() const
595{
596        return fEncodingStr;
597}
598
599inline XMLFileLoc XMLReader::getLineNumber() const
600{
601    return fCurLine;
602}
603
604inline bool XMLReader::getNoMoreFlag() const
605{
606        return fNoMore;
607}
608
609inline const XMLCh* XMLReader::getPublicId() const
610{
611        return fPublicId;
612}
613
614inline XMLSize_t XMLReader::getReaderNum() const
615{
616        return fReaderNum;
617}
618
619inline XMLReader::RefFrom XMLReader::getRefFrom() const
620{
621        return fRefFrom;
622}
623
624inline XMLReader::Sources XMLReader::getSource() const
625{
626        return fSource;
627}
628
629inline const XMLCh* XMLReader::getSystemId() const
630{
631        return fSystemId;
632}
633
634inline bool XMLReader::getThrowAtEnd() const
635{
636        return fThrowAtEnd;
637}
638
639inline XMLReader::Types XMLReader::getType() const
640{
641        return fType;
642}
643
644// ---------------------------------------------------------------------------
645//  XMLReader: Setter methods
646// ---------------------------------------------------------------------------
647inline void XMLReader::setReaderNum(const XMLSize_t newNum)
648{
649        fReaderNum = newNum;
650}
651
652inline void XMLReader::setThrowAtEnd(const bool newValue)
653{
654        fThrowAtEnd = newValue;
655}
656
657inline void XMLReader::setXMLVersion(const XMLVersion version)
658{
659        fXMLVersion = version;
660        if (version == XMLV1_1)
661        {
662                fNEL = true;
663                fgCharCharsTable = XMLChar1_1::fgCharCharsTable1_1;
664        }
665        else
666        {
667                fNEL = XMLChar1_0::enableNEL;
668                fgCharCharsTable = XMLChar1_0::fgCharCharsTable1_0;
669        }
670}
671
672// ---------------------------------------------------------------------------
673//  XMLReader: getNextChar() method inlined for speed
674// ---------------------------------------------------------------------------
675inline bool XMLReader::getNextChar(XMLCh& chGotten)
676{
677        //
678        //  See if there is at least a char in the buffer. Else, do the buffer
679        //  reload logic.
680        //
681        if (unlikely(fCharIndex >= fCharsAvail))
682        {
683                if (unlikely(!refreshCharBuffer()))
684                        return false;
685        }
686
687        chGotten = fCharBuf[fCharIndex++];
688
689        // Handle end of line normalization and line/col member maintenance.
690        //
691        // we can have end-of-line combinations with a leading
692        // chCR(xD), chLF(xA), chNEL(x85), or chLineSeparator(x2028)
693        //
694        // 0000000000001101 chCR
695        // 0000000000001010 chLF
696        // 0000000010000101 chNEL
697        // 0010000000101000 chLineSeparator
698        // -----------------------
699        // 1101111101010000 == ~(chCR|chLF|chNEL|chLineSeparator)
700        //
701        // if the result of the logical-& operation is
702        // true  : 'curCh' can not be chCR, chLF, chNEL or chLineSeparator
703        // false : 'curCh' can be chCR, chLF, chNEL or chLineSeparator
704        //
705        if ( chGotten & (XMLCh) ~(chCR|chLF|chNEL|chLineSeparator) )
706        {
707                fCurCol++;
708        }
709        else
710        {
711                handleEOL(chGotten, false);
712        }
713
714        return true;
715}
716
717// ---------------------------------------------------------------------------
718//  XMLReader: peekNextChar() method inlined for speed
719// ---------------------------------------------------------------------------
720inline bool XMLReader::peekNextChar(XMLCh& chGotten)
721{
722        //  If there is something still in the buffer, get it. Else do the reload
723        //  scenario.
724        //
725        if (unlikely(fCharIndex >= fCharsAvail))
726        {
727                // Try to refresh the buffer
728                if (unlikely(!refreshCharBuffer()))
729                {
730                        chGotten = chNull;
731                        return false;
732                }
733        }
734
735        chGotten = fCharBuf[fCharIndex];
736
737        //
738        //  Even though we are only peeking, we have to act the same as the
739        //  normal char get method in regards to newline normalization, though
740        //  its not as complicated as the actual character getting method's.
741        //
742        if ((chGotten == chCR || (fNEL && (chGotten == chNEL || chGotten == chLineSeparator)))
743                && (fSource == Source_External))
744                chGotten = chLF;
745
746        return true;
747}
748
749// ---------------------------------------------------------------------------
750//  XMLReader: Refresh Raw Buffer Methods
751// ---------------------------------------------------------------------------
752void XMLReader::refreshRawBuffer(const XMLSize_t from, const XMLSize_t to)
753{
754        #ifdef PRINT_DEBUG_MESSAGE
755        // clear out the "used" data from the buffer if and only if we're going to print it out
756        Array<XMLByte>::memzero(&fRawByteBuf[0], to);
757        #endif
758
759        Array<XMLByte>::move(&fRawByteBuf[from], &fRawByteBuf[to], (fRawBytesRead - from));
760
761        // instruct the XMLReader to update its raw data buffer
762        refreshRawBuffer(to + (fRawBytesRead - from));
763}
764
765void XMLReader::refreshRawBuffer(const XMLSize_t offset)
766{
767        fRawBytesRead = fStream->readBytes(&fRawByteBuf[offset], (kRawBufSize + sizeof(BytePack)) - offset) + offset;
768
769        if (likely(fRawBytesRead > kRawBufSize))
770        {
771                fRawBytesAvail = kRawBufSize;
772        }
773        else // we're at the end of file once we finish processing this
774        {
775                fRawBytesAvail = fRawBytesRead;
776                #ifdef PRINT_DEBUG_MESSAGE
777                // clear out the "used" data from the buffer if and only if we're going to print it out
778                Array<XMLByte>::memzero(&fRawByteBuf[fRawBytesRead], (kRawBufSize - fRawBytesRead));
779                #endif
780        }
781        fRawBufIndex = 0;
782}
783
784// ---------------------------------------------------------------------------------------
785
786XERCES_CPP_NAMESPACE_END
787
788#include <icxmlc/XMLParser.hpp>
789
790XERCES_CPP_NAMESPACE_BEGIN
791
792// ---------------------------------------------------------------------------------------
793
794template<class XMLScannerType>
795bool
796XMLReader::scanDocument( XMLScannerType * const scanner )
797{
798    // construct the actual XMLParser object to parse the ELEMENT and MISC nodes
799    XMLParserImpl<XMLScannerType>
800        parser
801        (
802            getReaderNum()
803            , scanner
804            , fTranscoder
805            , fMemoryManager
806        );
807
808    //  Scan the PROLOG part, which is everything before the root element
809        //  including the DTD subsets.
810        scanner->scanProlog();
811
812    // now construct the character set adapter
813    if (unlikely(!constructCharacterSetAdapter()))
814    {
815        scanner->emitError(XMLErrs::BadXMLEncoding, fEncodingStr);
816        return 0;
817    }
818
819    parser.init(fCharacterSetAdapter, fTranscoder, fCurLine, fCurCol, fXMLVersion);
820
821        fParser = (XMLParser*)&parser;
822
823        CALLGRIND_START_INSTRUMENTATION;
824
825        register XMLSize_t offset = fSrcOfsBase;
826        for (XMLSize_t i = 0; i < fCharIndex; i++)
827        {
828                offset += fCharSizeBuf[i];
829        }
830
831        refreshRawBuffer(offset, 0);
832
833        // transform the new raw data into symbol and content streams
834        parser.preScanDocumentPage
835        (
836                fRawByteBuf
837                , fRawBytesAvail
838                , fRawBytesRead <= kRawBufSize
839                , this
840        );
841
842        DEBUG_TRANSITION_MESSAGE
843        ("######################################################################");
844        DEBUG_TRANSITION_MESSAGE("SCANNING ELEMENT(S)")
845        DEBUG_TRANSITION_MESSAGE
846        ("######################################################################");
847
848    while (likely(parser.scanElementPage()))
849        {
850                parser.prepareForNextDocumentPage();
851
852                // transform the new raw data into symbol and content streams
853                parser.preScanDocumentPage
854                (
855                        fRawByteBuf
856                        , fRawBytesAvail
857                        , fRawBytesRead <= kRawBufSize
858                        , this
859                );
860        }
861
862    DEBUG_TRANSITION_MESSAGE
863    ("######################################################################");
864    DEBUG_TRANSITION_MESSAGE("SCANNING MISCELLANEOUS")
865    DEBUG_TRANSITION_MESSAGE
866    ("######################################################################");
867
868    while (unlikely(parser.scanMiscellaneousPage()))
869    {
870        parser.prepareForNextDocumentPage();
871
872        // transform the new raw data into symbol and content streams
873        parser.preScanDocumentPage
874        (
875            fRawByteBuf
876            , fRawBytesAvail
877            , fRawBytesRead <= kRawBufSize
878            , this
879        );
880    }
881
882
883        CALLGRIND_STOP_INSTRUMENTATION;
884        CALLGRIND_DUMP_STATS;
885
886        fNoMore = true;
887
888        parser.popReader();
889
890        fParser = 0;
891
892        return 1;
893}
894
895// -------------------------------------------------------------------------------------
896
897template <class XMLScannerType>
898IDISA_ALWAYS_INLINE
899XMLParserImpl<XMLScannerType> *
900XMLReader::scanFirst( XMLScannerType * const scanner )
901{
902    // construct the actual XMLParser object to parse the ELEMENT and MISC nodes
903    XMLParserImpl<XMLScannerType> * parser =
904        new XMLParserImpl<XMLScannerType>
905        (
906            getReaderNum()
907            , scanner
908            , fTranscoder
909            , fMemoryManager
910        );
911
912    //  Scan the PROLOG part, which is everything before the root element
913        //  including the DTD subsets.
914        scanner->scanProlog();
915
916        // now construct the character set adapter
917        if (unlikely(!constructCharacterSetAdapter()))
918        {
919                scanner->emitError(XMLErrs::BadXMLEncoding, fEncodingStr);
920                return 0;
921        }
922
923    parser->init(fCharacterSetAdapter, fTranscoder, fCurLine, fCurCol, fXMLVersion);
924
925        fParser = (XMLParser*)parser;
926
927        XMLSize_t offset = fSrcOfsBase;
928        for (XMLSize_t i = 0; i < fCharIndex; i++)
929        {
930                offset += fCharSizeBuf[i];
931        }
932        refreshRawBuffer(offset, 0);
933
934        // transform the new raw data into symbol and content streams
935        parser->preScanDocumentPage
936        (
937                fRawByteBuf
938                , fRawBytesAvail
939                , fRawBytesRead <= kRawBufSize
940                , this
941        );
942
943        fNoMore = false;
944
945        DEBUG_TRANSITION_MESSAGE
946        ("######################################################################");
947        DEBUG_TRANSITION_MESSAGE("SCANNING ELEMENT(S)")
948        DEBUG_TRANSITION_MESSAGE
949        ("######################################################################");
950
951        return parser;
952}
953
954// -------------------------------------------------------------------------------------
955
956template <class XMLScannerType>
957IDISA_ALWAYS_INLINE
958bool
959XMLReader::scanNext(XMLParserImpl<XMLScannerType> & parser)
960{
961        if (unlikely(fNoMore)) return 0;
962
963        XMLParser::XMLScanState r = parser.scanNext();
964
965        if (unlikely(r != XMLParser::HasMoreData))
966        {
967                if (likely(r == XMLParser::EndOfPage))
968                {           
969                        if (unlikely(fRawBytesAvail == 0))
970                        {
971                                fNoMore = 1;
972                                fParser = 0;
973                                return 0;
974                        }
975
976            if (unlikely(fRawBytesRead <= kRawBufSize))
977            {
978                fNoMore = 1;
979                fParser = 0;
980                return 0;
981            }
982
983                        parser.prepareForNextDocumentPage();
984
985                        parser.preScanDocumentPage
986                        (
987                                fRawByteBuf
988                                , fRawBytesAvail
989                                , fRawBytesRead <= kRawBufSize
990                                , this
991                        );
992
993            parser.preScanElementPage();
994                }
995                else
996                {
997                        DEBUG_TRANSITION_MESSAGE
998                        ("######################################################################");
999                        DEBUG_TRANSITION_MESSAGE("SCANNING MISCELLANEOUS")
1000                        DEBUG_TRANSITION_MESSAGE
1001                        ("######################################################################");
1002
1003            while (unlikely(parser.scanMiscellaneousPage()))
1004                        {
1005                                // if there is no new data; we're done (and the file is likely in error)
1006                                if (likely(fRawBytesRead <= kRawBufSize)) break;
1007
1008                                parser.prepareForNextDocumentPage();
1009
1010                                // transform the new raw data into symbol and content streams
1011                                parser.preScanDocumentPage
1012                                (
1013                                        fRawByteBuf
1014                                        , fRawBytesAvail
1015                                        , fRawBytesRead <= kRawBufSize
1016                                        , this
1017                                );
1018                        }
1019
1020                        fNoMore = 1;
1021                        fParser = 0;
1022                        return 0;
1023                }
1024        }
1025        return 1;
1026}
1027
1028inline
1029void XMLReader::getCurrentLineColumn(XMLFileLoc & line, XMLFileLoc & col) const
1030{
1031        if (likely(fParser != NULL))
1032        {
1033                fParser->getCurrentLineCol(line, col);
1034        }
1035        else // we're in Xerces prolog mode!
1036        {
1037                line = fCurLine;
1038                col = fCurCol;
1039        }
1040}
1041
1042
1043// ---------------------------------------------------------------------------
1044// DEPRECATED FUNCTIONS
1045// ---------------------------------------------------------------------------
1046inline void XMLReader::movePlainContentChars(XMLBuffer &)
1047{
1048        DEPRECATED_FEATURE_IN_ICXML;
1049}
1050
1051inline bool XMLReader::getNextCharIfNot(const XMLCh, XMLCh &)
1052{
1053        DEPRECATED_FEATURE_IN_ICXML;
1054}
1055
1056#undef CHAR_SIZE
1057#undef SYMBOL_POSITION
1058#undef SYMBOL_ARRAY_SIZE
1059#undef CONSTRUCT_CHARACTER_SET_ADAPTER
1060
1061XERCES_CPP_NAMESPACE_END
1062
1063#endif
Note: See TracBrowser for help on using the repository browser.