source: icXML/icXML-devel/src/icxmlc/parsers/XMLDocumentDisseminator.hpp @ 3151

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

Updates for icxmlc files.

File size: 7.3 KB
Line 
1#ifndef XMLDOCUMENTHANDLER_HPP
2#define XMLDOCUMENTHANDLER_HPP
3
4#include <icxercesc/framework/XMLAttDef.hpp>
5#include <icxercesc/framework/XMLElementDecl.hpp>
6#include <xercesc/framework/psvi/PSVIAttribute.hpp>
7#include <icxmlc/XMLParserDefs.hpp>
8#include <icxmlc/XMLParser.hpp>
9#include <icxercesc/framework/XMLDocumentHandler.hpp>
10#include <xercesc/sax/DocumentHandler.hpp>
11#include <xercesc/sax2/ContentHandler.hpp>
12#include <icxmlc/XMLConfig.hpp>
13
14XERCES_CPP_NAMESPACE_BEGIN
15
16class XMLDocumentDisseminator
17{
18    typedef DocumentContextStream::Type ContextType;
19    typedef PSVIAttribute::VALIDITY_STATE VALIDITY_STATE;
20    typedef PSVIAttribute::ASSESSMENT_TYPE ASSESSMENT_TYPE;
21    typedef XMLAttDef::AttTypes AttType;
22
23public:
24
25    XMLDocumentDisseminator(XMLParser & parser, XMLDocumentHandler * docHandler, MemoryManager * manager)
26    : fDocumentContextIdx(parser.fDocumentContextIdx)
27    , fDocumentObjectIdx(parser.fDocumentObjectIdx)
28    , fDocumentObjectCount(parser.fDocumentObjectCount)
29    , fContextIdx(parser.fContextIdx)
30    , fDocumentContextStream(parser.fDocumentContextStream)
31    , fDocumentObjectStream(parser.fDocumentObjectStream)
32    , fContextStream(parser.fContextStream)
33    , fDocumentHandler(docHandler)
34    , fContextId(0)
35    , fAttrList(16, true, manager)
36    {
37
38    }
39
40public:
41
42    IDISA_ALWAYS_INLINE
43    bool next();
44
45    IDISA_ALWAYS_INLINE
46    void resizeAttributeArray(const XMLSize_t maxAttributeCount, MemoryManager * manager);
47
48private:
49
50    IDISA_ALWAYS_INLINE
51    void readContextId();
52
53private:
54    size_t &                            fDocumentContextIdx;
55    size_t &                            fDocumentObjectIdx;
56    size_t &                            fDocumentObjectCount;
57    size_t &                            fContextIdx;
58    XMLDocumentHandler * const          fDocumentHandler;
59    gid_t                               fContextId;
60
61    DocumentContextStream &             fDocumentContextStream;
62    DocumentObjectStream &              fDocumentObjectStream;
63    SymbolUriArray &                                    fContextStream;
64
65    RefVectorOf<XMLAttr>                fAttrList;
66};
67
68bool XMLDocumentDisseminator::next()
69{
70    if (unlikely(fDocumentObjectCount == 0))
71    {
72        return 0;
73    }
74    fDocumentObjectCount--;
75
76    assert (fDocumentHandler != 0);
77
78    MarkupType type = static_cast<MarkupType>(fDocumentContextStream[fDocumentContextIdx++]);
79    XMLSize_t attributeCount = 0;
80
81    switch (type & MarkupMask)
82    {
83        case Content:
84            {
85                XMLSize_t length = fDocumentContextStream[fDocumentContextIdx++];
86                const XMLCh * content = fDocumentObjectStream[fDocumentObjectIdx++].string;
87                const bool nonWhitespace = (type & IgnorableWhitespace) == Content;
88                if (likely(nonWhitespace))
89                {
90                    fDocumentHandler->docCharacters(content, length, false);
91                }
92                else
93                {
94                    fDocumentHandler->ignorableWhitespace(content, length, false);
95                }
96            }
97            break;
98        case StartTagWithAttributes:           
99            attributeCount = fDocumentContextStream[fDocumentContextIdx++];
100            for (size_t index = 0; index < attributeCount; index++)
101            {
102                const ContextType attributeType = fDocumentContextStream[fDocumentContextIdx++];
103                const AttType attType = static_cast<AttType>(attributeType >> 16);
104                const bool specified = (attributeType & DefaultAttribute) != DefaultAttribute;
105                unsigned int uriId = fDocumentContextStream[fDocumentContextIdx++];
106                XMLSize_t length = fDocumentContextStream[fDocumentContextIdx++];
107                const QName * name = fDocumentObjectStream[fDocumentObjectIdx++].name;
108                const XMLCh * value = fDocumentObjectStream[fDocumentObjectIdx++].string;
109                const_cast<QName*>(name)->setURI(uriId);
110                XMLAttr & attr = *fAttrList.elementAt(index);
111                attr.set(name, value, length, attType);
112                attr.setSpecified(specified);
113            }
114            // falls through intentionally to build the start tag
115        case StartTagWithoutAttributes:
116            {
117                const bool isEmpty = (type >> 8) & 1;
118                //const bool isRoot = (type >> 16) & 1;
119                unsigned int uriId = fDocumentContextStream[fDocumentContextIdx++];
120                XMLElementDecl & elemDecl = const_cast<XMLElementDecl&>(*(fDocumentObjectStream[fDocumentObjectIdx++].decl));
121                QName * elemName = const_cast<QName*>(fDocumentObjectStream[fDocumentObjectIdx++].name);
122                elemName->setURI(uriId);
123                const QName * const grammarName = elemDecl.fElementName;
124                elemDecl.fElementName = elemName;
125                readContextId();
126                fDocumentHandler->startElement(elemDecl, uriId, elemName->getPrefix(), fAttrList, attributeCount, isEmpty, 0);
127                elemDecl.fElementName = grammarName;
128            }
129            break;
130        case EndTag:
131            {
132                unsigned int uriId = fDocumentContextStream[fDocumentContextIdx++];
133                XMLElementDecl & elemDecl = const_cast<XMLElementDecl&>(*(fDocumentObjectStream[fDocumentObjectIdx++].decl));
134                QName * elemName = const_cast<QName*>(fDocumentObjectStream[fDocumentObjectIdx++].name);
135                elemName->setURI(uriId);
136                const QName * const grammarName = elemDecl.fElementName;
137                elemDecl.fElementName = elemName;
138                readContextId();
139                fDocumentHandler->endElement(elemDecl, uriId, 0, elemName->getPrefix());
140                elemDecl.fElementName = grammarName;
141            }
142            break;
143        case ProcessingInstruction:
144            {
145                const XMLCh * target = fDocumentObjectStream[fDocumentObjectIdx++].string;
146                const XMLCh * data = fDocumentObjectStream[fDocumentObjectIdx++].string;
147                fDocumentHandler->docPI(target, data);
148            }
149            break;
150        case Comment:
151            {
152                const XMLCh * comment = fDocumentObjectStream[fDocumentObjectIdx++].string;
153                fDocumentHandler->docComment(comment);
154            }
155            break;
156        case CDATA:
157            {
158                XMLSize_t length = fDocumentContextStream[fDocumentContextIdx++];
159                const XMLCh * chars = fDocumentObjectStream[fDocumentObjectIdx++].string;
160                fDocumentHandler->docCharacters(chars, length, true);
161            }
162            break;
163         default:
164            UNREACHABLE;
165    }
166
167    return 1;
168}
169
170void XMLDocumentDisseminator::readContextId()
171{
172    // the namespace context id allows the scanner to map prefix to uris and determine what
173    // prefixes and uris are in scope.
174    fDocumentHandler->fNamespaceContextId = fContextStream[fContextIdx++];
175}
176
177void XMLDocumentDisseminator::resizeAttributeArray(const XMLSize_t maxAttributeCount, MemoryManager * manager)
178{
179    // resize the attribute list up front
180    if (unlikely(maxAttributeCount > fAttrList.size()))
181    {
182        size_t toAdd = maxAttributeCount - fAttrList.size();
183        do
184        {
185            fAttrList.addElement(new (manager) XMLAttr(manager));
186        }
187        while (--toAdd);
188    }
189}
190
191XERCES_CPP_NAMESPACE_END
192
193#endif // XMLDOCUMENTHANDLER_HPP
Note: See TracBrowser for help on using the repository browser.