source: icXML/icXML-devel/src/icxmlc/XMLScanIterator.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.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: XMLScanIterator.hpp 209 2012-12-02 21:17:04Z robc $
10 *
11 */
12
13#ifndef XMLSCANITERATOR_HPP
14#define XMLSCANITERATOR_HPP
15
16#include <icxmlc/XMLConfig.hpp>
17
18XERCES_CPP_NAMESPACE_BEGIN
19
20typedef scanword_t iterator_t;
21
22/// ---------------------------------------------------------------------------------------------------------------
23
24template <XMLCh Char>
25class XMLChIterator
26{
27public:
28
29        XMLChIterator(const XMLCh* string, const XMLSize_t length)
30        : fIterator(0)
31        , fOffset(0)
32        , fPosition(0)
33        , fNextOffset(0)
34        , fString(string)
35        , fLength(length)
36        {
37                scan();
38        }
39
40        bool next()
41        {
42                while (!fIterator)
43                {
44                        if (unlikely(!scan()))
45                        {
46                                return 0;
47                        }
48                }
49
50                fPosition = fOffset + scan_forward_zeroes(fIterator);
51                fIterator &= (fIterator - 1);
52
53                return 1;
54        }
55
56        iterator_t pos()
57        {
58                return fPosition;
59        }
60
61private:
62
63        inline iterator_t load(const BytePack * string, size_t index)
64        {
65                const BytePack mask1 = simd<16>::constant<Char>();
66
67                BytePack b0 = bitblock::load_unaligned(&string[index]);
68                BytePack b1 = bitblock::load_unaligned(&string[index + 1]);
69
70                BytePack t0 = simd<16>::eq(b0, mask1);
71                BytePack t1 = simd<16>::eq(b1, mask1);
72
73                return hsimd<8>::signmask(hsimd128<16>::packss(t1, t0));
74        }
75
76        inline bool scan()
77        {
78                if (unlikely(fLength == 0))
79                {
80                        return 0;
81                }
82
83                iterator_t value = 0;
84
85                fOffset = fNextOffset;
86
87                const BytePack * string = reinterpret_cast<const BytePack*>(&fString[fNextOffset]);
88
89                #ifdef __ARCH_64
90                if (fLength >= 64)
91                {
92                        value = load(string, 0) | (load(string, 2) << 16) | (load(string, 4) << 32) | (load(string, 6) << 48);
93
94                        fNextOffset += 64;
95                        fLength -= 64;
96                }
97                else
98                #endif
99                if (fLength >= 32)
100                {
101                        value = load(string, 0) | (load(string, 2) << 16);
102
103                        fNextOffset += 32;
104                        fLength -= 32;
105                }
106                else
107                {
108                        value = load(string, 0);
109
110                        if (fLength >= 16)
111                        {
112                                fNextOffset += 16;
113                                fLength -= 16;
114                        }
115                        else
116                        {
117                                fLength = 0;
118                        }
119                }
120
121                fIterator = value;
122
123                return 1;
124        }
125
126
127private:
128
129        iterator_t                              fIterator;
130        iterator_t                              fOffset;
131        iterator_t                              fPosition;
132
133        iterator_t                              fNextOffset;
134        const XMLCh *                   fString;
135        XMLSize_t                               fLength;
136
137};
138
139/// ---------------------------------------------------------------------------------------------------------------
140
141template <XMLCh Char1, XMLCh Char2>
142class XMLChIterator2
143{
144public:
145
146        XMLChIterator2(const XMLCh* string, const XMLSize_t length)
147        : fIterator(0)
148        , fOffset(0)
149        , fPosition(0)
150        , fNextOffset(0)
151        , fString(string)
152        , fLength(length)
153        {
154                scan();
155        }
156
157
158        bool next()
159        {
160                while (!fIterator)
161                {
162                        if (unlikely(!scan()))
163                        {
164                                return 0;
165                        }
166                }
167
168                fPosition = fOffset + scan_forward_zeroes(fIterator);
169                fIterator &= (fIterator - 1);
170
171                return 1;
172        }
173
174        iterator_t pos()
175        {
176                return fPosition;
177        }
178
179private:
180
181        inline iterator_t load(const BytePack * string, size_t index)
182        {
183                const BytePack mask1 = simd<16>::constant<Char1>();
184                const BytePack mask2 = simd<16>::constant<Char2>();
185
186                BytePack b0 = bitblock::load_unaligned(&string[index]);
187                BytePack b1 = bitblock::load_unaligned(&string[index + 1]);
188
189                BytePack t0 = simd<16>::eq(b0, mask1);
190                t0 = simd_or(t0, simd<16>::eq(b0, mask2));
191
192                BytePack t1 = simd<16>::eq(b1, mask1);
193                t1 = simd_or(t1, simd<16>::eq(b1, mask2));
194
195                return hsimd<8>::signmask(hsimd128<16>::packss(t1, t0));
196        }
197
198        inline bool scan()
199        {
200                if (unlikely(fLength == 0))
201                {
202                        return 0;
203                }
204
205                iterator_t value = 0;
206
207                fOffset = fNextOffset;
208
209                const BytePack * string = reinterpret_cast<const BytePack*>(&fString[fNextOffset]);
210
211                #ifdef __ARCH_64
212                if (fLength >= 64)
213                {
214                        value = load(string, 0) | (load(string, 2) << 16) | (load(string, 4) << 32) | (load(string, 6) << 48);
215
216                        fNextOffset += 64;
217                        fLength -= 64;
218                }
219                else
220                #endif
221                if (fLength >= 32)
222                {
223                        value = load(string, 0) | (load(string, 2) << 16);
224
225                        fNextOffset += 32;
226                        fLength -= 32;
227                }
228                else
229                {
230                        value = load(string, 0);
231
232                        if (fLength >= 16)
233                        {
234                                fNextOffset += 16;
235                                fLength -= 16;
236                        }
237                        else
238                        {
239                                fLength = 0;
240                        }
241                }
242
243                fIterator = value;
244
245                return 1;
246        }
247
248
249
250private:
251
252        iterator_t                              fIterator;
253        iterator_t                              fOffset;
254        iterator_t                              fPosition;
255
256        iterator_t                              fNextOffset;
257        const XMLCh *                   fString;
258        XMLSize_t                               fLength;
259
260};
261
262
263/// ---------------------------------------------------------------------------------------------------------------
264
265template <XMLCh Char1, XMLCh Char2, XMLCh Char3>
266class XMLChIterator3
267{
268public:
269
270        XMLChIterator3(const XMLCh* string, const XMLSize_t length)
271        : fIterator(0)
272        , fOffset(0)
273        , fPosition(0)
274        , fNextOffset(0)
275        , fString(string)
276        , fLength(length)
277        {
278                scan();
279        }
280
281
282        bool next()
283        {
284                while (!fIterator)
285                {
286                        if (unlikely(!scan()))
287                        {
288                                return 0;
289                        }
290                }
291
292                fPosition = fOffset + scan_forward_zeroes(fIterator);
293                fIterator &= (fIterator - 1);
294
295                return 1;
296        }
297
298        iterator_t pos()
299        {
300                return fPosition;
301        }
302
303private:
304
305        inline iterator_t load(const BytePack * string, size_t index)
306        {
307                const BytePack mask1 = simd<16>::constant<Char1>();
308                const BytePack mask2 = simd<16>::constant<Char2>();
309                const BytePack mask3 = simd<16>::constant<Char3>();
310
311                BytePack b0 = bitblock::load_unaligned(&string[index]);
312                BytePack b1 = bitblock::load_unaligned(&string[index + 1]);
313
314                BytePack t0 = simd<16>::eq(b0, mask1);
315                t0 = simd_or(t0, simd<16>::eq(b0, mask2));
316                t0 = simd_or(t0, simd<16>::eq(b0, mask3));
317
318                BytePack t1 = simd<16>::eq(b1, mask1);
319                t1 = simd_or(t1, simd<16>::eq(b1, mask2));
320                t1 = simd_or(t1, simd<16>::eq(b1, mask3));
321
322                return hsimd<8>::signmask(hsimd128<16>::packss(t1, t0));
323        }
324
325        bool scan()
326        {
327                if (unlikely(fLength == 0))
328                {
329                        return 0;
330                }
331
332                iterator_t value = 0;
333
334                fOffset = fNextOffset;
335
336                const BytePack * string = reinterpret_cast<const BytePack*>(&fString[fNextOffset]);
337
338                #ifdef __ARCH_64
339                if (fLength >= 64)
340                {
341                        value = load(string, 0) | (load(string, 2) << 16) | (load(string, 4) << 32) | (load(string, 6) << 48);
342
343                        fNextOffset += 64;
344                        fLength -= 64;
345                }
346                else
347                #endif
348                if (fLength >= 32)
349                {
350                        value = load(string, 0) | (load(string, 2) << 16);
351
352                        fNextOffset += 32;
353                        fLength -= 32;
354                }
355                else
356                {
357                        value = load(string, 0);
358
359                        if (fLength >= 16)
360                        {
361                                fNextOffset += 16;
362                                fLength -= 16;
363                        }
364                        else
365                        {
366                                fLength = 0;
367                        }
368                }
369
370                fIterator = value;
371
372                return 1;
373        }
374
375
376
377private:
378
379        iterator_t                              fIterator;
380        iterator_t                              fOffset;
381        iterator_t                              fPosition;
382
383        iterator_t                              fNextOffset;
384        const XMLCh *                   fString;
385        XMLSize_t                               fLength;
386
387};
388
389
390
391XERCES_CPP_NAMESPACE_END
392
393#endif // XMLSCANITERATOR_HPP
Note: See TracBrowser for help on using the repository browser.