source: icXML/icXML-devel/src/icxmlc/XMLStreamIterator.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: 6.1 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: XMLStreamIterator.hpp 207 2012-12-02 20:38:22Z robc $
10 *
11 */
12
13#ifndef XMLSTREAMITERATOR_HPP
14#define XMLSTREAMITERATOR_HPP
15
16#include <icxmlc/XMLConfig.hpp>
17
18XERCES_CPP_NAMESPACE_BEGIN
19
20typedef scanword_t iterator_t;
21
22struct XMLStreamIterator
23{
24public:
25
26        enum
27        {
28                BITS_PER_ITERATOR            = (sizeof(iterator_t) * 8)
29                , SCANS_PER_BLOCK            = (BLOCK_SIZE / BITS_PER_ITERATOR)
30                , LOG_2_CHARS_PER_ITERATOR   = CONST_LOG_2(BITS_PER_ITERATOR)
31                , LOG_2_SCANS_PER_BLOCK      = CONST_LOG_2(SCANS_PER_BLOCK)
32        };
33
34        XMLStreamIterator
35        (
36                const BitBlock & stream
37                , const iterator_t log2CodePointSize = 0
38                , const iterator_t offset = 0
39        )
40        : fStream(reinterpret_cast<const iterator_t *>(&stream))
41        , fLog2CodePointSize(log2CodePointSize)
42        , fIndex(0)
43        , fCount(SCANS_PER_BLOCK)
44        , fOffset(offset)
45        , fTransitions(fStream[0])
46        {
47
48        }
49
50        XMLStreamIterator
51        (
52                const ubitblock & stream
53                , const iterator_t log2CodePointSize = 0
54                , const iterator_t offset = 0
55        )
56        #ifdef __ARCH_64
57        : fStream(reinterpret_cast<const iterator_t *>(&stream._64))
58        #else
59        : fStream(reinterpret_cast<const iterator_t *>(&stream._32))
60        #endif
61        , fLog2CodePointSize(log2CodePointSize)
62        , fIndex(0)
63        , fCount(SCANS_PER_BLOCK)
64        , fOffset(offset)
65        , fTransitions(fStream[0])
66        {
67
68        }
69
70        XMLStreamIterator
71        (
72                const BitBlock * stream
73                , const iterator_t log2CodePointSize
74                , const iterator_t index = 0
75                , const iterator_t count = 1
76                , const iterator_t offset = 0
77        )
78        : fStream(reinterpret_cast<const iterator_t *>(stream))
79        , fLog2CodePointSize(log2CodePointSize)
80        , fIndex(index << LOG_2_SCANS_PER_BLOCK)
81        , fCount(count << LOG_2_SCANS_PER_BLOCK)
82        , fTransitions(fStream[index << LOG_2_SCANS_PER_BLOCK])
83        , fOffset(offset)
84        {
85
86        }
87
88        IDISA_ALWAYS_INLINE
89        bool next(unsigned int & currentPosition)
90        {
91                while (unlikely(fTransitions == 0))
92                {
93                        if (++fIndex != fCount)
94                        {
95                                fTransitions = fStream[fIndex];
96                                continue;
97                        }
98                        return false;
99                }
100
101                currentPosition = getNextPosition();
102                return true;
103        }
104
105        IDISA_ALWAYS_INLINE
106        bool next(size_t & currentPosition)
107        {
108                while (unlikely(fTransitions == 0))
109                {
110                        if (++fIndex != fCount)
111                        {
112                                fTransitions = fStream[fIndex];
113                                continue;
114                        }
115                        return false;
116                }
117
118                currentPosition = getNextPosition();
119                return true;
120        }
121
122        IDISA_ALWAYS_INLINE
123        bool next(int & currentPosition)
124        {
125                while (unlikely(fTransitions == 0))
126                {
127                        if (++fIndex != fCount)
128                        {
129                                fTransitions = fStream[fIndex];
130                                continue;
131                        }
132                        return false;
133                }
134
135                currentPosition = getNextPosition();
136                return true;
137        }
138
139        iterator_t getIndex()
140        {
141                return fIndex >> LOG_2_SCANS_PER_BLOCK;
142        }
143
144
145        iterator_t getCount()
146        {
147                return fCount >> LOG_2_SCANS_PER_BLOCK;
148        }
149
150        void setCount(iterator_t count)
151        {
152                fCount = count << LOG_2_SCANS_PER_BLOCK;
153        }
154
155private:
156
157        // -- if the bit streams are densely packed, would it be better to compute a scan_index
158        // -- offset once each time it's incremented?
159
160        IDISA_ALWAYS_INLINE
161        unsigned int getNextPosition()
162        {
163                const iterator_t position = ((fIndex << LOG_2_CHARS_PER_ITERATOR) | scan_forward_zeroes(fTransitions)) << fLog2CodePointSize;
164
165                // remove this transition bit from the transition stream
166                fTransitions &= (fTransitions - 1);
167
168                return fOffset + position;
169        }
170
171private:
172
173        const iterator_t     * const fStream;
174        iterator_t                   fTransitions;
175        iterator_t                   fIndex;
176        iterator_t                                       fCount;
177        const iterator_t                         fOffset;
178        const iterator_t                         fLog2CodePointSize;
179};
180
181struct XMLReverseStreamIterator
182{
183public:
184
185        enum
186        {
187                BITS_PER_ITERATOR            = (sizeof(iterator_t) * 8)
188                , SCANS_PER_BLOCK            = (BLOCK_SIZE / BITS_PER_ITERATOR)
189                , LOG_2_CHARS_PER_ITERATOR   = CONST_LOG_2(BITS_PER_ITERATOR)
190                , LOG_2_SCANS_PER_BLOCK      = CONST_LOG_2(SCANS_PER_BLOCK)
191        };
192
193        XMLReverseStreamIterator
194        (
195                const BitBlock & stream
196                , const iterator_t log2CodePointSize = 0
197        )
198        : fStream(reinterpret_cast<const iterator_t *>(&stream))
199        , fTransitions(fStream[SCANS_PER_BLOCK - 1])
200        , fIndex(SCANS_PER_BLOCK - 1)
201        , fLog2CodePointSize(log2CodePointSize)
202        , fCount(SCANS_PER_BLOCK)
203        {
204
205        }
206
207        XMLReverseStreamIterator
208        (
209                const ubitblock & stream
210                , const iterator_t log2CodePointSize = 0
211        )
212        #ifdef __ARCH_64
213        : fStream(reinterpret_cast<const iterator_t *>(&stream._64))
214        #else
215        : fStream(reinterpret_cast<const iterator_t *>(&stream._32))
216        #endif
217        , fTransitions(fStream[SCANS_PER_BLOCK - 1])
218        , fIndex(SCANS_PER_BLOCK - 1)
219        , fLog2CodePointSize(log2CodePointSize)
220        , fCount(SCANS_PER_BLOCK)
221        {
222
223        }
224
225        XMLReverseStreamIterator
226        (
227                const BitBlock * stream
228                , const iterator_t log2CodePointSize
229                , const iterator_t count
230        )
231        : fStream(reinterpret_cast<const iterator_t *>(stream))
232        , fIndex((count << LOG_2_SCANS_PER_BLOCK) - 1)
233        , fTransitions(fStream[fIndex])
234        , fLog2CodePointSize(log2CodePointSize)
235        , fCount(count << LOG_2_SCANS_PER_BLOCK)
236        {
237
238        }
239
240        IDISA_ALWAYS_INLINE
241        bool next()
242        {
243                while (unlikely(fTransitions == 0))
244                {
245                        if (fIndex--)
246                        {
247                                fTransitions = fStream[fIndex];
248                                continue;
249                        }
250                        return false;
251                }
252
253                fPosition = getNextPosition();
254                return true;
255        }
256
257        IDISA_ALWAYS_INLINE
258        iterator_t pos() const
259        {
260                return fPosition;
261        }
262
263private:
264
265        // -- since the bit streams are densely packed, would it be better to compute a scan_index
266        // -- offset once each time it's incremented?
267
268        IDISA_ALWAYS_INLINE
269        unsigned int getNextPosition()
270        {
271                const iterator_t one = 1;
272                const iterator_t position =
273                        (((fIndex << LOG_2_CHARS_PER_ITERATOR) | scan_backward_zeroes(fTransitions)) << fLog2CodePointSize);
274                // remove this transition bit from the transition stream
275                fTransitions ^= (one << position);
276                return position;
277        }
278
279private:
280
281        const iterator_t     * const fStream;
282        iterator_t                   fTransitions;
283        iterator_t                   fIndex;
284        const iterator_t                         fCount;
285        const iterator_t                         fLog2CodePointSize;
286        iterator_t                                       fPosition;
287};
288
289#undef __ARCH_64
290
291XERCES_CPP_NAMESPACE_END
292
293#endif // XMLSTREAMITERATOR_HPP
Note: See TracBrowser for help on using the repository browser.