source: icXML/icXML-devel/src/icxmlc/XMLScanIterator.hpp @ 3582

Last change on this file since 3582 was 3582, checked in by nmedfort, 5 years ago

bug fix for 32-bit version.

File size: 28.0 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 384 2013-10-21 22:28:13Z nigelm $
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    , fComplementMask(0)
37        {
38                scan();
39        }
40
41        bool next()
42        {
43                while (!fIterator)
44                {
45                        if (unlikely(!scan()))
46                        {
47                                return 0;
48                        }
49                }
50
51        const size_t pos = scan_forward_zeroes(fIterator);
52
53        fPosition = fOffset + pos;
54
55                fIterator &= (fIterator - 1);
56
57        fComplementMask &= ~mask(pos);
58        fComplementMask &= (fComplementMask - 1);
59
60                return 1;
61        }
62
63    bool nextc()
64    {
65        iterator_t temp = (~fIterator) & fComplementMask;
66        while (!temp)
67        {
68            if (likely(scan()))
69            {               
70                temp = (~fIterator) & fComplementMask;
71                continue;
72            }
73            return 0;
74        }
75
76        const iterator_t pos = scan_forward_zeroes(temp);
77        fPosition = fOffset + pos;
78        fIterator &= ~mask(pos);
79        return 1;
80    }
81
82        iterator_t pos()
83        {
84                return fPosition;
85        }
86
87private:
88
89    IDISA_ALWAYS_INLINE
90    static iterator_t mask(const size_t pos)
91    {
92        return (static_cast<iterator_t>(1) << pos) - static_cast<iterator_t>(1);
93    }
94
95    IDISA_ALWAYS_INLINE
96    static iterator_t load(const BytePack * string, size_t index)
97        {
98        BytePack b0 = bitblock::load_unaligned(&string[index]);
99        BytePack b1 = bitblock::load_unaligned(&string[index + 1]);
100
101        const BytePack mask1 = simd<16>::constant<Char>();
102                BytePack t0 = simd<16>::eq(b0, mask1);
103                BytePack t1 = simd<16>::eq(b1, mask1);
104
105        const iterator_t value = hsimd<8>::signmask(hsimd<16>::packss(t1, t0));
106
107        return value;
108        }
109
110    IDISA_ALWAYS_INLINE
111    bool scan()
112    {
113        if (unlikely(fLength == 0))
114        {
115            return 0;
116        }
117
118        fOffset = fNextOffset;
119
120        const BytePack * string = reinterpret_cast<const BytePack*>(&fString[fNextOffset]);
121
122        #ifdef __ARCH_64
123        if (likely(fLength >= 64))
124        {
125            fComplementMask = static_cast<iterator_t>(0xFFFFFFFFFFFFFFFFL);
126            fIterator = load(string, 0) | (load(string, 2) << 16) | (load(string, 4) << 32) | (load(string, 6) << 48);
127            fNextOffset += 64;
128            fLength -= 64;
129        }
130        else
131        {
132            if (fLength >= 48)
133            {
134                fComplementMask = mask(48 | (fLength & 15));
135                fIterator = (load(string, 0) | (load(string, 2) << 16) | (load(string, 4) << 32) | (load(string, 6) << 48));
136            }
137            else if (fLength >= 32)
138            {
139                fComplementMask = mask(32 | (fLength & 15));
140                fIterator = (load(string, 0) | (load(string, 2) << 16) | (load(string, 4) << 32));
141            }
142            else
143            {
144                fComplementMask = mask(fLength);
145                fIterator = (load(string, 0) | (load(string, 2) << 16));
146            }
147            fIterator &= fComplementMask;
148            fLength = 0;
149        }
150        #else
151        if (likely(fLength >= 32))
152        {
153            fComplementMask = static_cast<iterator_t>(0xFFFFFFFF);
154            fIterator = (load(string, 0) | (load(string, 2) << 16));
155            fNextOffset += 32;
156            fLength -= 32;
157        }
158        else
159        {
160            if (fLength >= 16)
161            {
162                fComplementMask = mask(16 | (fLength & 15));
163                fIterator = (load(string, 0) | (load(string, 2) << 16));
164            }
165            else
166            {
167                fComplementMask = mask(fLength);
168                fIterator = (load(string, 0) | (load(string, 2) << 16));
169            }
170            fIterator &= fComplementMask;
171            fLength = 0;
172        }
173        #endif
174
175        return 1;
176    }
177
178
179private:
180
181        iterator_t                              fIterator;
182        iterator_t                              fOffset;
183        iterator_t                              fPosition;
184
185        iterator_t                              fNextOffset;
186        const XMLCh *                   fString;
187    size_t                  fLength;
188    iterator_t              fComplementMask;
189};
190
191/// ---------------------------------------------------------------------------------------------------------------
192
193template <XMLCh Char1, XMLCh Char2>
194class XMLChIterator2
195{
196public:
197
198        XMLChIterator2(const XMLCh* string, const XMLSize_t length)
199        : fIterator(0)
200        , fOffset(0)
201        , fPosition(0)
202        , fNextOffset(0)
203        , fString(string)
204        , fLength(length)
205    , fComplementMask(0)
206        {
207                scan();
208        }
209
210
211    bool next()
212    {
213        while (!fIterator)
214        {
215            if (unlikely(!scan()))
216            {
217                return 0;
218            }
219        }
220
221        const size_t pos = scan_forward_zeroes(fIterator);
222
223        fPosition = fOffset + pos;
224
225        fIterator &= (fIterator - 1);
226
227        fComplementMask &= ~mask(pos);
228        fComplementMask &= (fComplementMask - 1);
229
230        return 1;
231    }
232
233    bool nextc()
234    {
235        iterator_t temp = (~fIterator) & fComplementMask;
236        while (!temp)
237        {
238            if (likely(scan()))
239            {
240                temp = (~fIterator) & fComplementMask;
241                continue;
242            }
243            return 0;
244        }
245
246        const iterator_t pos = scan_forward_zeroes(temp);
247        fPosition = fOffset + pos;
248        fIterator &= ~mask(pos);
249        return 1;
250    }
251
252
253        iterator_t pos()
254        {
255                return fPosition;
256        }
257
258private:
259
260    IDISA_ALWAYS_INLINE
261    static iterator_t mask(const size_t pos)
262    {
263        return (static_cast<iterator_t>(1) << pos) - static_cast<iterator_t>(1);
264    }
265
266    IDISA_ALWAYS_INLINE
267    iterator_t load(const BytePack * string, size_t index)
268        {
269                const BytePack mask1 = simd<16>::constant<Char1>();
270                const BytePack mask2 = simd<16>::constant<Char2>();
271
272                BytePack b0 = bitblock::load_unaligned(&string[index]);
273                BytePack b1 = bitblock::load_unaligned(&string[index + 1]);
274
275                BytePack t0 = simd<16>::eq(b0, mask1);
276        BytePack t1 = simd<16>::eq(b1, mask1);
277
278                t0 = simd_or(t0, simd<16>::eq(b0, mask2));
279                t1 = simd_or(t1, simd<16>::eq(b1, mask2));
280
281        return hsimd<8>::signmask(hsimd<16>::packss(t1, t0));
282        }
283
284    IDISA_ALWAYS_INLINE
285    bool scan()
286    {
287        if (unlikely(fLength == 0))
288        {
289            return 0;
290        }
291
292        fOffset = fNextOffset;
293
294        const BytePack * string = reinterpret_cast<const BytePack*>(&fString[fNextOffset]);
295
296        #ifdef __ARCH_64
297        if (likely(fLength >= 64))
298        {
299            fComplementMask = static_cast<iterator_t>(0xFFFFFFFFFFFFFFFFL);
300            fIterator = load(string, 0) | (load(string, 2) << 16) | (load(string, 4) << 32) | (load(string, 6) << 48);
301            fNextOffset += 64;
302            fLength -= 64;
303        }
304        else
305        {
306            if (fLength >= 48)
307            {
308                fComplementMask = mask(48 | (fLength & 15));
309                fIterator = (load(string, 0) | (load(string, 2) << 16) | (load(string, 4) << 32) | (load(string, 6) << 48));
310            }
311            else if (fLength >= 32)
312            {
313                fComplementMask = mask(32 | (fLength & 15));
314                fIterator = (load(string, 0) | (load(string, 2) << 16) | (load(string, 4) << 32));
315            }
316            else
317            {
318                fComplementMask = mask(fLength);
319                fIterator = (load(string, 0) | (load(string, 2) << 16));
320            }
321            fIterator &= fComplementMask;
322            fLength = 0;
323        }
324        #else
325        if (likely(fLength >= 32))
326        {
327            fComplementMask = static_cast<iterator_t>(0xFFFFFFFF);
328            fIterator = (load(string, 0) | (load(string, 2) << 16));
329            fNextOffset += 32;
330            fLength -= 32;
331        }
332        else
333        {
334            if (fLength >= 16)
335            {
336                fComplementMask = mask(16 | (fLength & 15));
337                fIterator = (load(string, 0) | (load(string, 2) << 16));
338            }
339            else
340            {
341                fComplementMask = mask(fLength);
342                fIterator = (load(string, 0) | (load(string, 2) << 16));
343            }
344            fIterator &= fComplementMask;
345            fLength = 0;
346        }
347        #endif
348
349        return 1;
350    }
351
352private:
353
354        iterator_t                              fIterator;
355        iterator_t                              fOffset;
356        iterator_t                              fPosition;
357
358        iterator_t                              fNextOffset;
359        const XMLCh *                   fString;
360    size_t                  fLength;
361    iterator_t              fComplementMask;
362};
363
364/// ---------------------------------------------------------------------------------------------------------------
365
366template <XMLCh Char1, XMLCh Char2, XMLCh Char3>
367class XMLChIterator3
368{
369public:
370
371        XMLChIterator3(const XMLCh* string, const XMLSize_t length)
372        : fIterator(0)
373        , fOffset(0)
374        , fPosition(0)
375        , fNextOffset(0)
376        , fString(string)
377        , fLength(length)
378    , fComplementMask(0)
379        {
380                scan();
381        }
382
383    bool next()
384    {
385        while (!fIterator)
386        {
387            if (unlikely(!scan()))
388            {
389                return 0;
390            }
391        }
392
393        const size_t pos = scan_forward_zeroes(fIterator);
394
395        fPosition = fOffset + pos;
396
397        fIterator &= (fIterator - 1);
398
399        fComplementMask &= ~mask(pos);
400        fComplementMask &= (fComplementMask - 1);
401
402        return 1;
403    }
404
405    bool nextc()
406    {
407        iterator_t temp = (~fIterator) & fComplementMask;
408        while (!temp)
409        {
410            if (likely(scan()))
411            {
412                temp = (~fIterator) & fComplementMask;
413                continue;
414            }
415            return 0;
416        }
417
418        const iterator_t pos = scan_forward_zeroes(temp);
419        fPosition = fOffset + pos;
420        fIterator &= ~mask(pos);
421        return 1;
422    }
423
424        iterator_t pos()
425        {
426                return fPosition;
427        }
428
429private:
430
431    IDISA_ALWAYS_INLINE
432    iterator_t load(const BytePack * string, size_t index)
433        {
434                const BytePack mask1 = simd<16>::constant<Char1>();
435                const BytePack mask2 = simd<16>::constant<Char2>();
436                const BytePack mask3 = simd<16>::constant<Char3>();
437
438                BytePack b0 = bitblock::load_unaligned(&string[index]);
439                BytePack b1 = bitblock::load_unaligned(&string[index + 1]);
440
441                BytePack t0 = simd<16>::eq(b0, mask1);
442                t0 = simd_or(t0, simd<16>::eq(b0, mask2));
443                t0 = simd_or(t0, simd<16>::eq(b0, mask3));
444
445                BytePack t1 = simd<16>::eq(b1, mask1);
446                t1 = simd_or(t1, simd<16>::eq(b1, mask2));
447                t1 = simd_or(t1, simd<16>::eq(b1, mask3));
448
449        return hsimd<8>::signmask(hsimd<16>::packss(t1, t0));
450        }
451
452    IDISA_ALWAYS_INLINE
453    static iterator_t mask(const size_t pos)
454    {
455        return (static_cast<iterator_t>(1) << pos) - static_cast<iterator_t>(1);
456    }
457
458    IDISA_ALWAYS_INLINE
459    bool scan()
460    {
461        if (unlikely(fLength == 0))
462        {
463            return 0;
464        }
465
466        fOffset = fNextOffset;
467
468        const BytePack * string = reinterpret_cast<const BytePack*>(&fString[fNextOffset]);
469
470        #ifdef __ARCH_64
471        if (likely(fLength >= 64))
472        {
473            fComplementMask = static_cast<iterator_t>(0xFFFFFFFFFFFFFFFFL);
474            fIterator = load(string, 0) | (load(string, 2) << 16) | (load(string, 4) << 32) | (load(string, 6) << 48);
475            fNextOffset += 64;
476            fLength -= 64;
477        }
478        else
479        {
480            if (fLength >= 48)
481            {
482                fComplementMask = mask(48 | (fLength & 15));
483                fIterator = (load(string, 0) | (load(string, 2) << 16) | (load(string, 4) << 32) | (load(string, 6) << 48));
484            }
485            else if (fLength >= 32)
486            {
487                fComplementMask = mask(32 | (fLength & 15));
488                fIterator = (load(string, 0) | (load(string, 2) << 16) | (load(string, 4) << 32));
489            }
490            else
491            {
492                fComplementMask = mask(fLength);
493                fIterator = (load(string, 0) | (load(string, 2) << 16));
494            }
495            fIterator &= fComplementMask;
496            fLength = 0;
497        }
498        #else
499        if (likely(fLength >= 32))
500        {
501            fComplementMask = static_cast<iterator_t>(0xFFFFFFFF);
502            fIterator = (load(string, 0) | (load(string, 2) << 16));
503            fNextOffset += 32;
504            fLength -= 32;
505        }
506        else
507        {
508            if (fLength >= 16)
509            {
510                fComplementMask = mask(16 | (fLength & 15));
511                fIterator = (load(string, 0) | (load(string, 2) << 16));
512            }
513            else
514            {
515                fComplementMask = mask(fLength);
516                fIterator = (load(string, 0) | (load(string, 2) << 16));
517            }
518            fIterator &= fComplementMask;
519            fLength = 0;
520        }
521        #endif
522
523        return 1;
524    }
525
526private:
527
528        iterator_t                              fIterator;
529        iterator_t                              fOffset;
530        iterator_t                              fPosition;
531
532        iterator_t                              fNextOffset;
533        const XMLCh *                   fString;
534    size_t                  fLength;
535    iterator_t              fComplementMask;
536};
537
538/// ---------------------------------------------------------------------------------------------------------------
539
540template <XMLCh Char1, XMLCh Char2, XMLCh Char3, XMLCh Char4>
541class XMLChIterator4
542{
543public:
544
545    XMLChIterator4(const XMLCh* string, const XMLSize_t length)
546    : fIterator(0)
547    , fOffset(0)
548    , fPosition(0)
549    , fNextOffset(0)
550    , fString(string)
551    , fLength(length)
552    , fComplementMask(0)
553    {
554        scan();
555    }
556
557    bool next()
558    {
559        while (!fIterator)
560        {
561            if (unlikely(!scan()))
562            {
563                return 0;
564            }
565        }
566
567        const size_t pos = scan_forward_zeroes(fIterator);
568
569        fPosition = fOffset + pos;
570
571        fIterator &= (fIterator - 1);
572
573        fComplementMask &= ~mask(pos);
574        fComplementMask &= (fComplementMask - 1);
575
576        return 1;
577    }
578
579    bool nextc()
580    {
581        iterator_t temp = (~fIterator) & fComplementMask;
582        while (!temp)
583        {
584            if (likely(scan()))
585            {
586                temp = (~fIterator) & fComplementMask;
587                continue;
588            }
589            return 0;
590        }
591
592        const iterator_t pos = scan_forward_zeroes(temp);
593        fPosition = fOffset + pos;
594        fIterator &= ~mask(pos);
595        return 1;
596    }
597
598    iterator_t pos()
599    {
600        return fPosition;
601    }
602
603private:
604
605    IDISA_ALWAYS_INLINE
606    iterator_t load(const BytePack * string, size_t index)
607    {
608        const BytePack mask1 = simd<16>::constant<Char1>();
609        const BytePack mask2 = simd<16>::constant<Char2>();
610        const BytePack mask3 = simd<16>::constant<Char3>();
611        const BytePack mask4 = simd<16>::constant<Char4>();
612
613        BytePack b0 = bitblock::load_unaligned(&string[index]);
614        BytePack b1 = bitblock::load_unaligned(&string[index + 1]);
615
616        BytePack t0 = simd<16>::eq(b0, mask1);
617        t0 = simd_or(t0, simd<16>::eq(b0, mask2));
618        t0 = simd_or(t0, simd<16>::eq(b0, mask3));
619        t0 = simd_or(t0, simd<16>::eq(b0, mask4));
620
621        BytePack t1 = simd<16>::eq(b1, mask1);
622        t1 = simd_or(t1, simd<16>::eq(b1, mask2));
623        t1 = simd_or(t1, simd<16>::eq(b1, mask3));
624        t1 = simd_or(t1, simd<16>::eq(b1, mask4));
625
626        return hsimd<8>::signmask(hsimd<16>::packss(t1, t0));
627    }
628
629    IDISA_ALWAYS_INLINE
630    static iterator_t mask(const size_t pos)
631    {
632        return (static_cast<iterator_t>(1) << pos) - static_cast<iterator_t>(1);
633    }
634
635    IDISA_ALWAYS_INLINE
636    bool scan()
637    {
638        if (unlikely(fLength == 0))
639        {
640            return 0;
641        }
642
643        fOffset = fNextOffset;
644
645        const BytePack * string = reinterpret_cast<const BytePack*>(&fString[fNextOffset]);
646
647        #ifdef __ARCH_64
648        if (likely(fLength >= 64))
649        {
650            fComplementMask = static_cast<iterator_t>(0xFFFFFFFFFFFFFFFFL);
651            fIterator = load(string, 0) | (load(string, 2) << 16) | (load(string, 4) << 32) | (load(string, 6) << 48);
652            fNextOffset += 64;
653            fLength -= 64;
654        }
655        else
656        {
657            if (fLength >= 48)
658            {
659                fComplementMask = mask(48 | (fLength & 15));
660                fIterator = (load(string, 0) | (load(string, 2) << 16) | (load(string, 4) << 32) | (load(string, 6) << 48));
661            }
662            else if (fLength >= 32)
663            {
664                fComplementMask = mask(32 | (fLength & 15));
665                fIterator = (load(string, 0) | (load(string, 2) << 16) | (load(string, 4) << 32));
666            }
667            else
668            {
669                fComplementMask = mask(fLength);
670                fIterator = (load(string, 0) | (load(string, 2) << 16));
671            }
672            fIterator &= fComplementMask;
673            fLength = 0;
674        }
675        #else
676        if (likely(fLength >= 32))
677        {
678            fComplementMask = static_cast<iterator_t>(0xFFFFFFFF);
679            fIterator = (load(string, 0) | (load(string, 2) << 16));
680            fNextOffset += 32;
681            fLength -= 32;
682        }
683        else
684        {
685            if (fLength >= 16)
686            {
687                fComplementMask = mask(16 | (fLength & 15));
688                fIterator = (load(string, 0) | (load(string, 2) << 16));
689            }
690            else
691            {
692                fComplementMask = mask(fLength);
693                fIterator = (load(string, 0) | (load(string, 2) << 16));
694            }
695            fIterator &= fComplementMask;
696            fLength = 0;
697        }
698        #endif
699
700        return 1;
701    }
702
703private:
704
705    iterator_t                          fIterator;
706    iterator_t                          fOffset;
707    iterator_t                          fPosition;
708
709    iterator_t                          fNextOffset;
710    const XMLCh *                       fString;
711    size_t                  fLength;
712    iterator_t              fComplementMask;
713};
714
715
716template <XMLCh CharLo1, XMLCh CharHi1, XMLCh CharLo2, XMLCh CharHi2>
717class XMLChRangeIterator2
718{
719public:
720
721    XMLChRangeIterator2(const XMLCh* string, const XMLSize_t length)
722    : fIterator(0)
723    , fOffset(0)
724    , fPosition(0)
725    , fNextOffset(0)
726    , fString(string)
727    , fLength(length)
728    , fComplementMask(0)
729    {
730        scan();
731    }
732
733    bool next()
734    {
735        while (!fIterator)
736        {
737            if (unlikely(!scan()))
738            {
739                return 0;
740            }
741        }
742
743        const size_t pos = scan_forward_zeroes(fIterator);
744
745        fPosition = fOffset + pos;
746
747        fIterator &= (fIterator - 1);
748
749        fComplementMask &= ~mask(pos);
750        fComplementMask &= (fComplementMask - 1);
751
752        return 1;
753    }
754
755    bool nextc()
756    {
757        iterator_t temp = (~fIterator) & fComplementMask;
758        while (!temp)
759        {
760            if (likely(scan()))
761            {
762                temp = (~fIterator) & fComplementMask;
763                continue;
764            }
765            return 0;
766        }
767
768        const iterator_t pos = scan_forward_zeroes(temp);
769        fPosition = fOffset + pos;
770        fIterator &= ~mask(pos);
771        return 1;
772    }
773
774    iterator_t pos()
775    {
776        return fPosition;
777    }
778
779private:
780
781    template <XMLCh lo, XMLCh hi>
782    IDISA_ALWAYS_INLINE
783    static BytePack within(const BytePack data)
784    {
785        BytePack a;
786        if (lo == 0)
787        {
788            a = simd<16>::eq(data, simd<16>::constant<0>());
789            a = simd_or(a, simd<16>::gt(data, simd<16>::constant<0>()));
790        }
791        else
792        {
793            a = simd<16>::gt(data, simd<16>::constant<lo - 1>());
794        }
795
796        BytePack b;
797        if (hi == 0xFFFF)
798        {
799            b = simd<16>::eq(data, simd<16>::constant<0xFFFF>());
800            b = simd_or(b, simd<16>::lt(data, simd<16>::constant<0xFFFF>()));
801        }
802        else
803        {
804            b = simd<16>::lt(data, simd<16>::constant<hi + 1>());
805        }
806
807        return simd_and(a, b);
808    }
809
810    IDISA_ALWAYS_INLINE
811    iterator_t load(const BytePack * string, size_t index)
812    {
813        BytePack b0 = bitblock::load_unaligned(&string[index]);
814        BytePack t0 = within<CharLo1, CharHi1>(b0);
815        t0 = simd_or(t0, within<CharLo2, CharHi2>(b0));
816
817        BytePack b1 = bitblock::load_unaligned(&string[index + 1]);
818        BytePack t1 = within<CharLo1, CharHi1>(b0);
819        t1 = simd_or(t1, within<CharLo2, CharHi2>(b1));
820
821        return hsimd<8>::signmask(hsimd<16>::packss(t1, t0));
822    }
823
824    IDISA_ALWAYS_INLINE
825    static iterator_t mask(const size_t pos)
826    {
827        return (static_cast<iterator_t>(1) << pos) - static_cast<iterator_t>(1);
828    }
829
830    IDISA_ALWAYS_INLINE
831    bool scan()
832    {
833        if (unlikely(fLength == 0))
834        {
835            return 0;
836        }
837
838        fOffset = fNextOffset;
839
840        const BytePack * string = reinterpret_cast<const BytePack*>(&fString[fNextOffset]);
841
842        #ifdef __ARCH_64
843        if (likely(fLength >= 64))
844        {
845            fComplementMask = static_cast<iterator_t>(0xFFFFFFFFFFFFFFFFL);
846            fIterator = load(string, 0) | (load(string, 2) << 16) | (load(string, 4) << 32) | (load(string, 6) << 48);
847            fNextOffset += 64;
848            fLength -= 64;
849        }
850        else
851        {
852            if (fLength >= 48)
853            {
854                fComplementMask = mask(48 | (fLength & 15));
855                fIterator = (load(string, 0) | (load(string, 2) << 16) | (load(string, 4) << 32) | (load(string, 6) << 48));
856            }
857            else if (fLength >= 32)
858            {
859                fComplementMask = mask(32 | (fLength & 15));
860                fIterator = (load(string, 0) | (load(string, 2) << 16) | (load(string, 4) << 32));
861            }
862            else
863            {
864                fComplementMask = mask(fLength);
865                fIterator = (load(string, 0) | (load(string, 2) << 16));
866            }
867            fIterator &= fComplementMask;
868            fLength = 0;
869        }
870        #else
871        if (likely(fLength >= 32))
872        {
873            fComplementMask = static_cast<iterator_t>(0xFFFFFFFF);
874            fIterator = (load(string, 0) | (load(string, 2) << 16));
875            fNextOffset += 32;
876            fLength -= 32;
877        }
878        else
879        {
880            if (fLength >= 16)
881            {
882                fComplementMask = mask(16 | (fLength & 15));
883                fIterator = (load(string, 0) | (load(string, 2) << 16));
884            }
885            else
886            {
887                fComplementMask = mask(fLength);
888                value = (load(string, 0) | (load(string, 2) << 16));
889            }
890            fIterator &= fComplementMask;
891            fLength = 0;
892        }
893        #endif
894
895        return 1;
896    }
897
898private:
899
900    iterator_t                          fIterator;
901    iterator_t                          fOffset;
902    iterator_t                          fPosition;
903
904    iterator_t                          fNextOffset;
905    const XMLCh *                       fString;
906    size_t                  fLength;
907    iterator_t              fComplementMask;
908};
909
910template <XMLCh CharLo1, XMLCh CharHi1, XMLCh CharLo2, XMLCh CharHi2, XMLCh CharLo3, XMLCh CharHi3, XMLCh CharLo4, XMLCh CharHi4>
911class XMLChRangeIterator4
912{
913public:
914
915    XMLChRangeIterator4(const XMLCh* string, const XMLSize_t length)
916    : fIterator(0)
917    , fOffset(0)
918    , fPosition(0)
919    , fNextOffset(0)
920    , fString(string)
921    , fLength(length)
922    , fComplementMask(0)
923    {
924        scan();
925    }
926
927    bool next()
928    {
929        while (!fIterator)
930        {
931            if (unlikely(!scan()))
932            {
933                return 0;
934            }
935        }
936
937        const size_t pos = scan_forward_zeroes(fIterator);
938
939        fPosition = fOffset + pos;
940
941        fIterator &= (fIterator - 1);
942
943        fComplementMask &= ~mask(pos);
944        fComplementMask &= (fComplementMask - 1);
945
946        return 1;
947    }
948
949    bool nextc()
950    {
951        iterator_t temp = (~fIterator) & fComplementMask;
952        while (!temp)
953        {
954            if (likely(scan()))
955            {
956                temp = (~fIterator) & fComplementMask;
957                continue;
958            }
959            return 0;
960        }
961
962        const iterator_t pos = scan_forward_zeroes(temp);
963        fPosition = fOffset + pos;
964        fIterator &= ~mask(pos);
965        return 1;
966    }
967
968    iterator_t pos()
969    {
970        return fPosition;
971    }
972
973private:
974
975    template <XMLCh lo, XMLCh hi>
976    IDISA_ALWAYS_INLINE
977    static BytePack within(const BytePack data)
978    {
979        BytePack a;
980        if (lo == 0)
981        {
982            a = simd<16>::eq(data, simd<16>::constant<0>());
983            a = simd_or(a, simd<16>::gt(data, simd<16>::constant<0>()));
984        }
985        else
986        {
987            a = simd<16>::gt(data, simd<16>::constant<lo - 1>());
988        }
989
990        BytePack b;
991        if (hi == 0xFFFF)
992        {
993            b = simd<16>::eq(data, simd<16>::constant<0xFFFF>());
994            b = simd_or(b, simd<16>::lt(data, simd<16>::constant<0xFFFF>()));
995        }
996        else
997        {
998            b = simd<16>::lt(data, simd<16>::constant<hi + 1>());
999        }
1000
1001        return simd_and(a, b);
1002    }
1003
1004    IDISA_ALWAYS_INLINE
1005    iterator_t load(const BytePack * string, size_t index)
1006    {
1007        BytePack b0 = bitblock::load_unaligned(&string[index]);
1008        BytePack t0 = within<CharLo1, CharHi1>(b0);
1009        t0 = simd_or(t0, within<CharLo2, CharHi2>(b0));
1010        t0 = simd_or(t0, within<CharLo3, CharHi3>(b0));
1011        t0 = simd_or(t0, within<CharLo4, CharHi4>(b0));
1012
1013        BytePack b1 = bitblock::load_unaligned(&string[index + 1]);
1014        BytePack t1 = within<CharLo1, CharHi1>(b0);
1015        t1 = simd_or(t1, within<CharLo2, CharHi2>(b1));
1016        t1 = simd_or(t1, within<CharLo3, CharHi3>(b1));
1017        t1 = simd_or(t1, within<CharLo4, CharHi4>(b1));
1018
1019        return hsimd<8>::signmask(hsimd<16>::packss(t1, t0));
1020    }
1021
1022    IDISA_ALWAYS_INLINE
1023    static iterator_t mask(const size_t pos)
1024    {
1025        return (static_cast<iterator_t>(1) << pos) - static_cast<iterator_t>(1);
1026    }
1027
1028    IDISA_ALWAYS_INLINE
1029    bool scan()
1030    {
1031        if (unlikely(fLength == 0))
1032        {
1033            return 0;
1034        }
1035
1036        fOffset = fNextOffset;
1037
1038        const BytePack * string = reinterpret_cast<const BytePack*>(&fString[fNextOffset]);
1039
1040        #ifdef __ARCH_64
1041        if (likely(fLength >= 64))
1042        {
1043            fComplementMask = static_cast<iterator_t>(0xFFFFFFFFFFFFFFFFL);
1044            fIterator = load(string, 0) | (load(string, 2) << 16) | (load(string, 4) << 32) | (load(string, 6) << 48);
1045            fNextOffset += 64;
1046            fLength -= 64;
1047        }
1048        else
1049        {
1050            if (fLength >= 48)
1051            {
1052                fComplementMask = mask(48 | (fLength & 15));
1053                fIterator = (load(string, 0) | (load(string, 2) << 16) | (load(string, 4) << 32) | (load(string, 6) << 48));
1054            }
1055            else if (fLength >= 32)
1056            {
1057                fComplementMask = mask(32 | (fLength & 15));
1058                fIterator = (load(string, 0) | (load(string, 2) << 16) | (load(string, 4) << 32));
1059            }
1060            else
1061            {
1062                fComplementMask = mask(fLength);
1063                fIterator = (load(string, 0) | (load(string, 2) << 16));
1064            }
1065            fIterator &= fComplementMask;
1066            fLength = 0;
1067        }
1068        #else
1069        if (likely(fLength >= 32))
1070        {
1071            fComplementMask = static_cast<iterator_t>(0xFFFFFFFF);
1072            fIterator = (load(string, 0) | (load(string, 2) << 16));
1073            fNextOffset += 32;
1074            fLength -= 32;
1075        }
1076        else
1077        {
1078            if (fLength >= 16)
1079            {
1080                fComplementMask = mask(16 | (fLength & 15));
1081                fIterator = (load(string, 0) | (load(string, 2) << 16));
1082            }
1083            else
1084            {
1085                fComplementMask = mask(fLength);
1086                fIterator = (load(string, 0) | (load(string, 2) << 16));
1087            }
1088            fIterator &= fComplementMask;
1089            fLength = 0;
1090        }
1091        #endif
1092
1093        return 1;
1094    }
1095
1096private:
1097
1098    iterator_t                          fIterator;
1099    iterator_t                          fOffset;
1100    iterator_t                          fPosition;
1101
1102    iterator_t                          fNextOffset;
1103    const XMLCh *                       fString;
1104    size_t                  fLength;
1105    iterator_t              fComplementMask;
1106};
1107
1108XERCES_CPP_NAMESPACE_END
1109
1110#endif // XMLSCANITERATOR_HPP
1111
Note: See TracBrowser for help on using the repository browser.