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

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

Updates for icxmlc files.

File size: 11.9 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: XMLSymbolTable.hpp 312 2013-05-10 20:53:22Z nigelm $
10 *
11 */
12
13#if !defined(XERCESC_INCLUDE_GUARD_XML_SYMBOL_TABLE_HPP)
14#define XERCESC_INCLUDE_GUARD_XML_SYMBOL_TABLE_HPP
15
16#include <icxmlc/stringpool.h>
17#include <icxmlc/XMLSymbol.hpp>
18#include <icxmlc/HashTable.hpp>
19#include <icxmlc/XMLStringU.hpp>
20#include <icxmlc/PopCounter.hpp>
21#include <icxmlc/XMLStreamIterator.hpp>
22#include <icxmlc/XMLReferenceTable.hpp>
23#include <icxmlc/XMLStringHash.hpp>
24#include <icxercesc/util/XMLString.hpp>
25#include <icxercesc/util/TransService.hpp>
26#include <icxmlc/XMLConfig.hpp>
27
28// TODO: split the hash table and data portion of the symbol and reference tables so that the symbols themselves are localized
29// in the XMLParser and the content vs. att val content is stored in seperate hash tables.
30
31XERCES_CPP_NAMESPACE_BEGIN
32
33class XMLScanner;
34class XMLTranscoder;
35class XMLNamespaceResolver;
36class XMLUTF8CharacterSetAdapter;
37class XMLUTF16CharacterSetAdapter;
38
39/* -------------------------------------------------------------------------------------------- */
40
41class XMLSymbolTable
42{
43        template<class XMLScanner> friend class XMLParserImpl;
44    friend class XMLUTF8CharacterSetAdapter;
45    friend class XMLUTF16CharacterSetAdapter;
46    friend class XMLReferenceTable;
47
48public:
49
50    enum PredefinedNCNames
51    {
52        Type = 0
53        , Nil = 1
54        , SchemaLocation = 2
55        , NoNamespaceSchemaLocation = 3
56        , PredefinedCount = 4
57    };
58
59public:
60
61        XMLSymbolTable
62        (
63        XMLScanner * const              scanner
64        , XMLNamespaceResolver &        namespaceResolver
65        , XMLReferenceTable &           referenceTable
66        , MemoryManager * const         manager
67        )
68        : fSymbolTable()
69        , fSymbolPool(manager)
70    , fNCNameTable(manager)
71    , fNamespaceResolver(namespaceResolver)
72    , fReferenceTable(referenceTable)
73    , fScanner(*scanner)
74    , fTranscoder(0)   
75        , fResumeSymbol(0)
76    , fDefaultAttributePool(manager)
77    , fHasDefaultAttributes(0)
78        , fMemoryManager(manager)
79        {
80        fNCNameTable.add(Type, SchemaSymbols::fgXSI_TYPE, 4);
81        fNCNameTable.add(Nil, SchemaSymbols::fgATT_NILL, 3);
82        fNCNameTable.add(SchemaLocation, SchemaSymbols::fgXSI_SCHEMALOCATION, 14);
83        fNCNameTable.add(NoNamespaceSchemaLocation, SchemaSymbols::fgXSI_NONAMESPACESCHEMALOCATION, 25);
84        }
85
86    ~XMLSymbolTable() { }
87
88    XMLSymbol & operator[](const gid_t gid)
89        {
90                return fSymbolTable[gid];
91        }
92
93    const XMLSymbol & operator[](const gid_t gid) const
94        {
95                return fSymbolTable[gid];
96        }
97
98    const XMLSize_t count() const
99    {
100        return fSymbolTable.count();
101    }
102
103
104    const XMLCh * getNCName(const gid_t id) const
105    {
106        return fNCNameTable[id];
107    }
108
109    template <unsigned int CodeUnitSize, bool Internal>
110    size_t resolve
111        (
112        const BitBlock *                        symbolMarkerStream
113        , const XMLByte * const         source
114        , const size_t              offset
115        , const size_t                          count
116        , gid_t *                   symbolStream
117        , size_t &                  bytesEaten
118        );
119
120        void setTranscoder(XMLTranscoder * transcoder)
121        {
122                fTranscoder = transcoder;
123        }
124
125        XMLTranscoder * getTranscoder() const
126        {
127                return fTranscoder;
128        }
129
130    bool hasDefaultAttributes() const
131    {
132        return fHasDefaultAttributes;
133    }
134
135    bool someDefaultAttributesContainReferences() const
136    {
137        return 0;
138    }
139
140protected:
141
142        /**
143         * get the entry with the matching symbol if it exists within this
144         * hash table
145         * @param id the correspondence id
146         * @return the symbol or NULL
147        */     
148    IDISA_ALWAYS_INLINE
149        gid_t   
150        addOrFind
151        (
152                const XMLByte                   * const rawSymbol
153                , const XMLSize_t                               rawLength
154        );
155
156    IDISA_ALWAYS_INLINE
157        gid_t
158        addOrFindInternal
159        (
160                const XMLCh                             * const key
161                , const XMLSize_t                               length
162        );
163
164    gid_t
165    add
166    (
167        const XMLByte                   * const rawSymbol
168        , const XMLSize_t                               rawLength
169    );
170
171    gid_t
172    addInternal
173    (
174        const XMLCh                             * const key
175        , const XMLSize_t                               length
176        , const XMLByte         * const unencodedKey
177        , const XMLSize_t               unencodedLength
178    );
179
180    IDISA_ALWAYS_INLINE
181    void doNamespaceResolution(const XMLCh * name, const XMLSize_t length, int & colon, XMLSymbol & entry);
182
183    IDISA_ALWAYS_INLINE
184    void checkForDefaultAttributes(XMLSymbol & entry);
185
186    IDISA_ALWAYS_INLINE
187    void initQName(XMLCh * name, const XMLSize_t length, const int colon, const XMLSymbol & entry, QName & qName) const;
188
189private:
190
191    HashTable<XMLSymbol, XMLByte, INITIAL_SYMBOL_TABLE_CAPACITY>                fSymbolTable;
192    StringPool<XMLByte, INITIAL_SYMBOL_TABLE_STRING_POOL_SIZE>                  fSymbolPool;
193
194    XMLStringHash<XMLStringPoolEntry, INITIAL_SYMBOL_TABLE_STRING_POOL_SIZE>    fNCNameTable;
195
196    XMLNamespaceResolver &                                                      fNamespaceResolver;
197    XMLReferenceTable &                                                         fReferenceTable;
198    XMLScanner &                                                                fScanner;
199
200    XMLTranscoder *                                                             fTranscoder;
201
202    bool                                                                        fResumeSymbol;
203
204    StringPool<XMLElementDefaultAttribute, 16>                                  fDefaultAttributePool;
205    bool                                                                        fHasDefaultAttributes;
206
207
208    MemoryManager *     const                                                       fMemoryManager;
209};
210
211/// ------------------------------------------------------------------------------------------------------------------------------------
212
213template <unsigned int CodeUnitSize, bool Internal>
214size_t XMLSymbolTable::resolve
215(
216    const BitBlock *                    symbolMarkerStream
217    , const XMLByte * const             source
218    , const size_t              offset
219    , const size_t                              count
220    , gid_t *                   symbolStream
221    , size_t &                  bytesEaten
222)
223{
224    XMLStreamIterator symbolItr(symbolMarkerStream, CONST_LOG_2(CodeUnitSize), count);
225
226    #if defined(PRINT_DEBUG_MESSAGE) && !defined(PRINT_DEBUG_IGNORE_SYMBOL_STREAM_MESSAGES)
227    size_t offsetIndex = 0;
228    XMLByte DATA_BLOCK[66] = {'|', 0};
229    enum
230    {
231        DATA_BLOCK_SIZE = (BLOCK_SIZE * CodeUnitSize)
232        , LOG_2_DATA_BLOCK_SIZE = CONST_LOG_2(DATA_BLOCK_SIZE)
233    };
234    #endif
235
236    DEBUG_SYMBOL_MESSAGE("######################################################################");
237    DEBUG_SYMBOL_MESSAGE("BEGIN " << (Internal ? "INTERNAL " : "") << "SYMBOL SCAN: Count=" << count << " Offset=" << offset << " CodeUnitSize=" << CodeUnitSize);
238    DEBUG_SYMBOL_MESSAGE("######################################################################");
239
240    ssize_t startPosition = -offset;
241    ssize_t endPosition;
242    bool resumeSymbol = 0;
243    gid_t * symbolPtr = symbolStream;
244
245    switch (fResumeSymbol)
246    {
247        case 0: while (unlikely(symbolItr.next()))
248                {
249                    startPosition = symbolItr.pos();
250
251        case 1:     if (unlikely(!symbolItr.next()))
252                    {
253                        bytesEaten = offset + startPosition >> Internal;
254                        resumeSymbol = 1;
255                        break;
256                    }
257
258                    endPosition = symbolItr.pos();
259
260                    #if defined(PRINT_DEBUG_MESSAGE) && !defined(PRINT_DEBUG_IGNORE_SYMBOL_STREAM_MESSAGES)
261                    for (; offsetIndex <= (endPosition >> LOG_2_DATA_BLOCK_SIZE); offsetIndex++)
262                    {
263                        for (unsigned int scanOffset = 0; scanOffset < DATA_BLOCK_SIZE; scanOffset += 64)
264                        {
265                            const size_t offset = (offsetIndex << LOG_2_DATA_BLOCK_SIZE) | scanOffset;
266                            const XMLByte * byteStream = &source[offset - 1];
267
268                            for (unsigned int i = 1; i <= 64; i++)
269                            {
270                                XMLByte c = byteStream[i];
271                                if (c < 32) c = ' ';
272                                DATA_BLOCK[i] = c;
273                            }
274
275                            DEBUG_SYMBOL_MESSAGE("----------------------------------------------------------------------");
276                            DEBUG_SYMBOL_MESSAGE(
277                                 XERCES_STD_QUALIFIER setw(5) <<
278                                 (offset) <<
279                                 XERCES_STD_QUALIFIER setw(0) <<
280                                 DATA_BLOCK );
281                            DEBUG_SYMBOL_MESSAGE("----------------------------------------------------------------------");
282                        }
283                    }
284                    #endif
285
286                    gid_t gid;
287                    if (Internal)
288                    {
289                        gid = addOrFindInternal(reinterpret_cast<const XMLCh*>(&source[startPosition]), (endPosition - startPosition) / sizeof(XMLCh));
290                    }
291                    else
292                    {
293                        gid = addOrFind(&source[startPosition], (endPosition - startPosition));
294                    }
295
296                    DEBUG_SYMBOL_MESSAGE
297                    (
298                        "SYMBOL: " << fSymbolTable[gid]
299                        << " @ {" << startPosition << ',' << endPosition << '}'
300                        << " gid=" << gid
301                    );
302
303                    *symbolPtr++ = gid;
304                }
305    }
306
307    #if defined(PRINT_DEBUG_MESSAGE) && !defined(PRINT_DEBUG_IGNORE_SYMBOL_STREAM_MESSAGES)
308    for (; offsetIndex < count; offsetIndex++)
309    {
310        for (unsigned int scanOffset = 0; scanOffset < DATA_BLOCK_SIZE; scanOffset += 64)
311        {
312            const size_t offset = (offsetIndex << LOG_2_DATA_BLOCK_SIZE) | scanOffset;
313            const XMLByte * byteStream = &source[offset - 1];
314
315            for (unsigned int i = 1; i <= 64; i++)
316            {
317                XMLByte c = byteStream[i];
318                if (c < 32) c = ' ';
319                DATA_BLOCK[i] = c;
320            }
321
322            DEBUG_SYMBOL_MESSAGE("----------------------------------------------------------------------");
323            DEBUG_SYMBOL_MESSAGE(
324                 XERCES_STD_QUALIFIER setw(5) <<
325                 (offset) <<
326                 XERCES_STD_QUALIFIER setw(0) <<
327                 DATA_BLOCK );
328            DEBUG_SYMBOL_MESSAGE("----------------------------------------------------------------------");
329        }
330    }
331    #endif
332
333    fResumeSymbol = resumeSymbol;   
334
335    DEBUG_SYMBOL_MESSAGE("XMLSymbolTable::fResumeSymbol=" << fResumeSymbol << ", bytesEaten=" << bytesEaten)
336
337    return symbolPtr - symbolStream;
338}
339
340/// ------------------------------------------------------------------------------------------------------------------------------------
341
342gid_t
343XMLSymbolTable::addOrFind
344(
345    const XMLByte                       * const key
346    , const XMLSize_t                           length
347)
348{
349    gid_t gid = fSymbolTable.find(key, length);
350    if (unlikely(gid == -1))
351    {
352        gid = add(key, length);
353    }
354    return gid;
355}
356
357/// ------------------------------------------------------------------------------------------------------------------------------------
358
359gid_t
360XMLSymbolTable::addOrFindInternal
361(
362    const XMLCh                         * const key
363    , const XMLSize_t                           length
364)
365{
366    XMLByte * unencodedKey = (XMLByte *)fMemoryManager->allocate((length * 3) + 1);
367    XMLSize_t unencodedLength;
368    unencodedLength = fTranscoder->transcodeTo(key, length, unencodedKey, length * 3, unencodedLength, XMLTranscoder::UnRep_Throw);
369    unencodedKey[unencodedLength] = 0;
370
371    gid_t gid = fSymbolTable.find(unencodedKey, unencodedLength);
372
373    if (unlikely(gid == -1))
374    {
375        gid = addInternal(key, length, unencodedKey, unencodedLength);
376    }
377    fMemoryManager->deallocate(unencodedKey);
378    return gid;
379}
380
381XERCES_CPP_NAMESPACE_END
382
383#endif // XML_SYMBOL_TABLE_H
Note: See TracBrowser for help on using the repository browser.