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

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

Fixes for icXML 0.9

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