source: icXML/icXML-devel/src/icxmlc/XMLParser.hpp @ 2720

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

Initial check-in of icXML 0.8 source files

File size: 8.6 KB
Line 
1/*
2 *  Copyright © 2012 International Characters.
3 *  This software is licensed to the public under the Open Software License 3.0.
4 *  icXML is a trademark of International Characters.
5 */
6
7/*
8 * @author Nigel Medforth, nigelm -at- interational-characters.com
9 * @version $Id: XMLParser.hpp 207 2012-12-02 20:38:22Z robc $
10 *
11 */
12
13#ifndef XMLPARSER_H
14#define XMLPARSER_H
15
16#include <icxmlc/XMLBlockCopy.h>
17#include <xercesc/util/TransService.hpp>
18#include <icxmlc/XMLLineColTracker.hpp>
19#include <icxmlc/XMLSymbol.hpp>
20#include <icxmlc/Array.hpp>
21#include <icxmlc/XMLAttributeList.hpp>
22#include <icxmlc/XMLNamespaceResolver.hpp>
23#include <xercesc/util/QName.hpp>
24#include <icxmlc/XMLStringHash.hpp>
25#include <icxmlc/RunLengthQueue.hpp>
26#include <xercesc/framework/XMLElementDecl.hpp>
27#include <xercesc/internal/XMLReader.hpp>
28#include <icxmlc/XMLSymbolTable.hpp>
29#include <icxmlc/XMLParserDefs.hpp>
30#include <icxmlc/XMLConfig.hpp>
31
32XERCES_CPP_NAMESPACE_BEGIN
33
34class XMLCharacterSetAdapter;
35class XMLScanner;
36
37/**
38
39 **/
40class XMLParser
41{
42
43    public:
44
45        enum DocumentStateType
46        {
47            Prolog
48            , Element
49            , Miscellaneous
50        };
51
52        enum XMLScanState
53        {
54            HasMoreData = 0
55            , EndOfPage = -1
56            , EndOfDocumentSection = 1
57        };
58
59        void getCurrentLineCol
60        (
61            XMLFileLoc                 &   line
62            , XMLFileLoc               &   col
63        ) const;
64
65        typedef XMLReader::XMLVersion XMLVersion;
66
67    protected:
68
69        XMLParser
70        (
71            unsigned int                                                readerNum
72            , XMLScanner *                      scanner
73            , XMLTranscoder *                                   transcoder
74            , XMLNamespaceResolver *                    namespaceResolver
75            , MemoryManager * const                             manager
76        );
77
78        virtual ~XMLParser() = 0;
79
80    protected:
81
82        SymbolArray                                                     fSymbolArray;
83        unsigned int                                            fSymbolCount;
84
85        SymbolUriArray                                          fSymbolUriArray;
86
87        /**
88        The namespace context id allows the scanner to map prefix to uris and determine what
89        prefixes and uris are in scope.
90        */
91        SymbolUriArray                                          fContextIdArray;
92
93        ContentStream                       fContentBuf;
94
95        StringPtrArray                                          fStringEndPtr;
96
97        const XMLCh **                      fCurrentStringEndPtr;
98        unsigned int                        fStringCount;
99
100        XMLCharacterSetAdapter *                        fCharacterSetAdapter;
101        XMLSymbolTable                                          fSymbolTable;
102
103        const XMLCh *                       fCursorPtr;
104        const XMLCh *                       fCursorEndPtr;
105        unsigned int                        fRawDataOffset;
106        unsigned int                        fSymbolIdx;
107        bool                                fInMarkup;
108        unsigned int                        fMarkupCount;
109        unsigned int                        fElementCount;
110        unsigned int                        fRawBytesAvail;
111        unsigned int                        fIncompleteMarkupBytes;
112        unsigned int                                            fUnusedSymbols;
113        unsigned int                                            fUnusedContent;
114
115        /// ------------------  ERROR HANDLING VARIABLES ---------------------- ///
116        XMLLineColTracker                   fCurrLineCol;
117        XMLLineColTracker                   fNextLineCol;
118        LineColStream                       fNewLineOrSkipMaskStream;
119        LineColStream                       fDelMaskStream;
120        unsigned int                        fLineColStartIndex;
121
122        const unsigned int                  fReaderNum;
123};
124
125// ---------------------------------------------------------------------------------------------------------
126
127IDISA_ALWAYS_INLINE
128XMLParser::XMLParser
129(
130    unsigned int                                                readerNum
131    , XMLScanner *                      scanner
132    , XMLTranscoder *                                   transcoder
133    , XMLNamespaceResolver *                    namespaceResolver
134    , MemoryManager * const                             manager
135)
136    #ifndef USE_HEAP_ALLOCATION_FOR_XML_PARSER
137    : fSymbolArray()
138    , fSymbolUriArray()
139    , fContextIdArray()
140    , fContentBuf()
141    , fStringEndPtr()
142    , fNewLineOrSkipMaskStream()
143    , fDelMaskStream()
144    #else
145    : fSymbolArray(INITIAL_SYMBOL_SIZE)
146    , fSymbolUriArray(INITIAL_SYMBOL_SIZE)
147    , fContextIdArray(INITIAL_SYMBOL_SIZE)
148    , fContentBuf(INITIAL_CONTENT_BUFFER_SIZE)
149    , fStringEndPtr(INITIAL_STRING_LENGTH_SIZE)
150    , fNewLineOrSkipMaskStream(INITIAL_LINE_COLUMN_SIZE)
151    , fDelMaskStream(INITIAL_LINE_COLUMN_SIZE)
152    #endif
153    , fSymbolCount(0)
154    , fCurrentStringEndPtr(&fStringEndPtr[0])
155    , fStringCount(0)
156    , fCharacterSetAdapter(0)
157    , fSymbolTable(transcoder, scanner, namespaceResolver, manager)
158    , fCursorPtr(&fContentBuf[0])
159    , fCursorEndPtr(&fContentBuf[0])
160    , fRawDataOffset(0)
161    , fInMarkup(0)
162    , fUnusedSymbols(0)
163    , fUnusedContent(0)
164    , fElementCount(0)
165    , fRawBytesAvail(0)
166    , fIncompleteMarkupBytes(0)
167    , fCurrLineCol()
168    , fNextLineCol()
169    , fLineColStartIndex(0)
170    , fReaderNum(readerNum)
171{
172
173}
174
175// -------------------------------------------------------------------------------------------
176
177IDISA_ALWAYS_INLINE
178XMLParser::~XMLParser()
179{
180
181}
182
183// -------------------------------------------------------------------------------------------
184
185IDISA_ALWAYS_INLINE
186void XMLParser::getCurrentLineCol
187(
188    XMLFileLoc     & line
189    , XMLFileLoc   & column
190) const
191{
192#ifndef DISABLE_PARSER_LINE_COLUMN_CALCULATION
193    XMLLineColTracker lineCol(fCurrLineCol);
194    size_t deletedChars = (fCursorPtr - &fContentBuf[0]);
195
196    size_t index = 0;
197
198    for (;;)
199    {
200        // NOTE: these fences are required here or we may get arbitary data from the
201        // streams
202        const BitBlock newLineOrSkipMask =
203            bitblock::load_aligned(&fNewLineOrSkipMaskStream[index]);
204        const BitBlock delMask =
205            bitblock::load_aligned(&fDelMaskStream[index]);
206
207        // set the next new line stream
208        const BitBlock newLine = simd_andc(newLineOrSkipMask, delMask);
209        const BitBlock skipMask = simd_and(newLineOrSkipMask, delMask);
210
211        lineCol.next(newLine, skipMask);
212
213        // invert the deleted mask to construct the non-deleted mask
214        ubitblock nonDelMask;
215        nonDelMask._128 = simd_not(delMask);
216
217        // count the full block to see if we can just accept the line as is
218        size_t count = bitblock::popcount(nonDelMask._128);
219
220        if (likely(deletedChars > count))
221        {
222            // our cursor is after this block; just pass through it
223            deletedChars -= count;
224            lineCol.advance();
225            index++;
226        }
227        else
228        {
229            if (unlikely(deletedChars == count))
230            {
231                lineCol.advance();
232                lineCol.get(line, column);
233                break;
234            }
235            else
236            {
237                // our cursor stopped somewhere in this block.
238                // find the true position.
239                size_t pos = 0;
240                #if 1
241                // TODO: some analysis is needed here to see whether 8, 16, 32
242                // or 64 bit popcounts perform better on average.
243                ubitblock pop;
244                pop._128 = simd128<8>::popcount(nonDelMask._128);
245                // count through the 8-bit pop counts to see which
246                // portion of the pop count array we end up on.
247
248                for (;;)
249                {
250                    count = pop._8[pos];
251                    if (likely(deletedChars >= count))
252                    {
253                        deletedChars -= count;
254                        pos++;
255                        continue;
256                    }
257                    else if (unlikely(deletedChars == 0))
258                    {
259                        pos = (pos << 3);
260                        break;
261                    }
262                    else
263                    {
264                        size_t itr = nonDelMask._8[pos];
265                        while (--deletedChars)
266                        {
267                            itr &= (itr - 1);
268                        }
269                        pos = (pos << 3) | scan_forward_zeroes(itr);
270                        break;
271                    }
272                }
273                #else
274                ForwardScanner<BitBlock, size_t> itr(&nonDelMask._128);
275                while (postDelCount--)
276                {
277                    itr.scan_to_next();
278                }
279                pos = itr.get_pos();
280                #endif
281                lineCol.get(pos, line, column);
282                break;
283            }
284        }
285    }
286#else
287    line = 0;
288    column = 0;
289#endif
290}
291
292XERCES_CPP_NAMESPACE_END
293
294#if !defined(XERCES_TMPLSINC)
295#include <icxmlc/XMLParserImpl.hpp>
296#endif
297
298#endif // XMLPARSER_H
Note: See TracBrowser for help on using the repository browser.