source: icXML/icXML-devel/src/icxercesc/validators/common/CMStateSet.hpp @ 3153

Last change on this file since 3153 was 2721, checked in by cameron, 7 years ago

Fix imports in icXML modified Xerces files

File size: 18.2 KB
Line 
1/*
2 * Licensed to the Apache Software Foundation (ASF) under one or more
3 * contributor license agreements.  See the NOTICE file distributed with
4 * this work for additional information regarding copyright ownership.
5 * The ASF licenses this file to You under the Apache License, Version 2.0
6 * (the "License"); you may not use this file except in compliance with
7 * the License.  You may obtain a copy of the License at
8 *
9 *      http://www.apache.org/licenses/LICENSE-2.0
10 *
11 * Unless required by applicable law or agreed to in writing, software
12 * distributed under the License is distributed on an "AS IS" BASIS,
13 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
14 * See the License for the specific language governing permissions and
15 * limitations under the License.
16 */
17
18/*
19 * $Id: CMStateSet.hpp 901107 2010-01-20 08:45:02Z borisk $
20 */
21
22#if !defined(XERCESC_INCLUDE_GUARD_CMSTATESET_HPP)
23#define XERCESC_INCLUDE_GUARD_CMSTATESET_HPP
24
25//  DESCRIPTION:
26//
27//  This class is a specialized bitset class for the content model code of
28//  the validator. It assumes that its never called with two objects of
29//  different bit counts, and that bit sets smaller than a threshold are far
30//  and away the most common. So it can be a lot more optimized than a general
31//  purpose utility bitset class
32//
33
34#include <xercesc/util/ArrayIndexOutOfBoundsException.hpp>
35#include <xercesc/util/RuntimeException.hpp>
36#include <icxercesc/util/PlatformUtils.hpp>
37#include <xercesc/framework/MemoryManager.hpp>
38#include <icxercesc/util/XMLString.hpp>
39#include <string.h>
40
41#if XERCES_HAVE_EMMINTRIN_H
42#   include <emmintrin.h>
43#endif
44
45XERCES_CPP_NAMESPACE_BEGIN
46
47class CMStateSetEnumerator;
48
49// This value must be 4 in order to use the SSE2 instruction set
50#define CMSTATE_CACHED_INT32_SIZE  4
51
52// This value must be a multiple of 128 in order to use the SSE2 instruction set
53#define CMSTATE_BITFIELD_CHUNK  1024
54#define CMSTATE_BITFIELD_INT32_SIZE (1024 / 32)
55
56struct CMDynamicBuffer
57{
58        //  fArraySize
59        //      This indicates the number of elements of the fBitArray vector
60        //
61        //  fBitArray
62        //      A vector of arrays of XMLInt32; each array is allocated on demand
63        //      if a bit needs to be set in that range
64        //
65        //  fMemoryManager
66        //      The memory manager used to allocate and deallocate memory
67        //
68        XMLSize_t       fArraySize;
69        XMLInt32**      fBitArray;
70        MemoryManager*  fMemoryManager;
71};
72
73class CMStateSet : public XMemory
74{
75public :
76        // -----------------------------------------------------------------------
77        //  Constructors and Destructor
78        // -----------------------------------------------------------------------
79        CMStateSet( const XMLSize_t bitCount
80                          , MemoryManager* const manager = XMLPlatformUtils::fgMemoryManager) :
81
82                fBitCount(bitCount)
83                , fDynamicBuffer(0)
84        {
85                //
86                //  See if we need to allocate the byte array or whether we can live
87                //  within the cached bit high performance scheme.
88                //
89                if (fBitCount > (CMSTATE_CACHED_INT32_SIZE * 32))
90                {
91                        fDynamicBuffer = (CMDynamicBuffer*)manager->allocate(sizeof(CMDynamicBuffer));
92                        fDynamicBuffer->fMemoryManager = manager;
93                        // allocate an array of vectors, each one containing CMSTATE_BITFIELD_CHUNK bits
94                        fDynamicBuffer->fArraySize = fBitCount / CMSTATE_BITFIELD_CHUNK;
95                        if (fBitCount % CMSTATE_BITFIELD_CHUNK)
96                                fDynamicBuffer->fArraySize++;
97                        fDynamicBuffer->fBitArray = (XMLInt32**) fDynamicBuffer->fMemoryManager->allocate(fDynamicBuffer->fArraySize*sizeof(XMLInt32*));
98                        for(XMLSize_t index = 0; index < fDynamicBuffer->fArraySize; index++)
99                                fDynamicBuffer->fBitArray[index]=NULL;
100                }
101                else
102                {
103                        for (XMLSize_t index = 0; index < CMSTATE_CACHED_INT32_SIZE; index++)
104                                fBits[index] = 0;
105                }
106        }
107
108        CMStateSet(const CMStateSet& toCopy) :
109                XMemory(toCopy)
110          , fBitCount(toCopy.fBitCount)
111          , fDynamicBuffer(0)
112        {
113                //
114                //  See if we need to allocate the byte array or whether we can live
115                //  within the cahced bit high performance scheme.
116                //
117                if (fBitCount > (CMSTATE_CACHED_INT32_SIZE * 32))
118                {
119                        fDynamicBuffer = (CMDynamicBuffer*) toCopy.fDynamicBuffer->fMemoryManager->allocate(sizeof(CMDynamicBuffer));
120                        fDynamicBuffer->fMemoryManager = toCopy.fDynamicBuffer->fMemoryManager;
121                        fDynamicBuffer->fArraySize = fBitCount / CMSTATE_BITFIELD_CHUNK;
122                        if (fBitCount % CMSTATE_BITFIELD_CHUNK)
123                                fDynamicBuffer->fArraySize++;
124                        fDynamicBuffer->fBitArray = (XMLInt32**) fDynamicBuffer->fMemoryManager->allocate(fDynamicBuffer->fArraySize*sizeof(XMLInt32*));
125                        for(XMLSize_t index = 0; index < fDynamicBuffer->fArraySize; index++)
126                        {
127                                if(toCopy.fDynamicBuffer->fBitArray[index]!=NULL)
128                                {
129                                        allocateChunk(index);
130                                        memcpy((void *) fDynamicBuffer->fBitArray[index],
131                                                   (const void *) toCopy.fDynamicBuffer->fBitArray[index],
132                                                   CMSTATE_BITFIELD_INT32_SIZE * sizeof(XMLInt32));
133                                }
134                                else
135                                        fDynamicBuffer->fBitArray[index]=NULL;
136                        }
137                }
138                else
139                {
140                        memcpy((void *) fBits,
141                                   (const void *) toCopy.fBits,
142                                   CMSTATE_CACHED_INT32_SIZE * sizeof(XMLInt32));
143                }
144        }
145
146        ~CMStateSet()
147        {
148                if(fDynamicBuffer)
149                {
150                        for(XMLSize_t index = 0; index < fDynamicBuffer->fArraySize; index++)
151                                if(fDynamicBuffer->fBitArray[index]!=NULL)
152                                        deallocateChunk(index);
153                        fDynamicBuffer->fMemoryManager->deallocate(fDynamicBuffer->fBitArray);
154                        fDynamicBuffer->fMemoryManager->deallocate(fDynamicBuffer);
155                }
156        }
157
158
159        // -----------------------------------------------------------------------
160        //  Set manipulation methods
161        // -----------------------------------------------------------------------
162        void operator|=(const CMStateSet& setToOr)
163        {
164                if(fDynamicBuffer==0)
165                {
166#ifdef XERCES_HAVE_SSE2_INTRINSIC
167                        if(XMLPlatformUtils::fgSSE2ok)
168                        {
169                                __m128i xmm1 = _mm_loadu_si128((__m128i*)fBits);
170                                __m128i xmm2 = _mm_loadu_si128((__m128i*)setToOr.fBits);
171                                __m128i xmm3 = _mm_or_si128(xmm1, xmm2);     //  OR  4 32-bit words
172                                _mm_storeu_si128((__m128i*)fBits, xmm3);
173                        }
174                        else
175#endif
176                        {
177                                for (XMLSize_t index = 0; index < CMSTATE_CACHED_INT32_SIZE; index++)
178                                        if(setToOr.fBits[index])
179                                        {
180                                                if(fBits[index])
181                                                        fBits[index] |= setToOr.fBits[index];
182                                                else
183                                                        fBits[index] = setToOr.fBits[index];
184                                        }
185                        }
186                }
187                else
188                {
189                        for (XMLSize_t index = 0; index < fDynamicBuffer->fArraySize; index++)
190                        {
191                                XMLInt32 *& other = setToOr.fDynamicBuffer->fBitArray[index];
192                                if(other!=NULL)
193                                {
194                                        // if we haven't allocated the subvector yet, allocate it and copy
195                                        if(fDynamicBuffer->fBitArray[index]==NULL)
196                                        {
197                                                allocateChunk(index);
198                                                memcpy((void *) fDynamicBuffer->fBitArray[index],
199                                                           (const void *) other,
200                                                           CMSTATE_BITFIELD_INT32_SIZE * sizeof(XMLInt32));
201                                        }
202                                        else
203                                        {
204                                                // otherwise, merge them
205                                                XMLInt32*& mine = fDynamicBuffer->fBitArray[index];
206#ifdef XERCES_HAVE_SSE2_INTRINSIC
207                                                if(XMLPlatformUtils::fgSSE2ok)
208                                                {
209                                                        for(XMLSize_t subIndex = 0; subIndex < CMSTATE_BITFIELD_INT32_SIZE; subIndex+=4)
210                                                        {
211                                                           __m128i xmm1 = _mm_load_si128((__m128i*)&other[subIndex]);
212                                                           __m128i xmm2 = _mm_load_si128((__m128i*)&mine[subIndex]);
213                                                           __m128i xmm3 = _mm_or_si128(xmm1, xmm2);     //  OR  4 32-bit words
214                                                           _mm_store_si128((__m128i*)&mine[subIndex], xmm3);
215                                                        }
216                                                }
217                                                else
218#endif
219                                                {
220                                                        for(XMLSize_t subIndex = 0; subIndex < CMSTATE_BITFIELD_INT32_SIZE; subIndex++)
221                                                                if(setToOr.fDynamicBuffer->fBitArray[index][subIndex])
222                                                                {
223                                                                        if(fDynamicBuffer->fBitArray[index][subIndex])
224                                                                                fDynamicBuffer->fBitArray[index][subIndex] |= setToOr.fDynamicBuffer->fBitArray[index][subIndex];
225                                                                        else
226                                                                                fDynamicBuffer->fBitArray[index][subIndex] = setToOr.fDynamicBuffer->fBitArray[index][subIndex];
227                                                                }
228                                                }
229                                        }
230                                }
231                        }
232                }
233        }
234
235        bool operator==(const CMStateSet& setToCompare) const
236        {
237                if (fBitCount != setToCompare.fBitCount)
238                        return false;
239
240                if(fDynamicBuffer==0)
241                {
242                        for (XMLSize_t index = 0; index < CMSTATE_CACHED_INT32_SIZE; index++)
243                        {
244                                if (fBits[index] != setToCompare.fBits[index])
245                                        return false;
246                        }
247                }
248                else
249                {
250                        for (XMLSize_t index = 0; index < fDynamicBuffer->fArraySize; index++)
251                        {
252                                XMLInt32 *& other = setToCompare.fDynamicBuffer->fBitArray[index],
253                                                 *& mine = fDynamicBuffer->fBitArray[index];
254                                if(mine==NULL && other==NULL)
255                                        continue;
256                                else if(mine==NULL || other==NULL) // the other should have been empty too
257                                        return false;
258                                else
259                                {
260                                        for(XMLSize_t subIndex = 0; subIndex < CMSTATE_BITFIELD_INT32_SIZE; subIndex++)
261                                                if(mine[subIndex]!=other[subIndex])
262                                                        return false;
263                                }
264                        }
265                }
266                return true;
267        }
268
269        CMStateSet& operator=(const CMStateSet& srcSet)
270        {
271                if (this == &srcSet)
272                        return *this;
273
274                // They have to be the same size
275                if (fBitCount != srcSet.fBitCount)
276                {
277                        if(fDynamicBuffer)
278                                ThrowXMLwithMemMgr(RuntimeException, XMLExcepts::Bitset_NotEqualSize, fDynamicBuffer->fMemoryManager);
279                        else
280                                ThrowXML(RuntimeException, XMLExcepts::Bitset_NotEqualSize);
281                }
282
283                if(fDynamicBuffer==0)
284                {
285                        for (XMLSize_t index = 0; index < CMSTATE_CACHED_INT32_SIZE; index++)
286                                fBits[index] = srcSet.fBits[index];
287                }
288                else
289                {
290                        for (XMLSize_t index = 0; index < fDynamicBuffer->fArraySize; index++)
291                                if(srcSet.fDynamicBuffer->fBitArray[index]==NULL)
292                                {
293                                        // delete this subentry
294                                        if(fDynamicBuffer->fBitArray[index]!=NULL)
295                                                deallocateChunk(index);
296                                }
297                                else
298                                {
299                                        // if we haven't allocated the subvector yet, allocate it and copy
300                                        if(fDynamicBuffer->fBitArray[index]==NULL)
301                                                allocateChunk(index);
302                                        memcpy((void *) fDynamicBuffer->fBitArray[index],
303                                                   (const void *) srcSet.fDynamicBuffer->fBitArray[index],
304                                                   CMSTATE_BITFIELD_INT32_SIZE * sizeof(XMLInt32));
305                                }
306                }
307                return *this;
308        }
309
310        XMLSize_t getBitCountInRange(XMLSize_t start, XMLSize_t end) const
311        {
312                XMLSize_t count = 0;
313                end /= 32;
314                if(fDynamicBuffer==0)
315                {
316                        if(end > CMSTATE_CACHED_INT32_SIZE)
317                                end = CMSTATE_CACHED_INT32_SIZE;
318                        for (XMLSize_t index = start / 32; index < end; index++)
319                        {
320                                if (fBits[index] != 0)
321                                        for(int i=0;i<32;i++)
322                                        {
323                                                const XMLInt32 mask = 1UL << i;
324                                                if(fBits[index] & mask)
325                                                        count++;
326                                        }
327                        }
328                }
329                else
330                {
331                        if(end > fDynamicBuffer->fArraySize)
332                                end = fDynamicBuffer->fArraySize;
333                        for (XMLSize_t index = start / 32; index < end; index++)
334                        {
335                                if(fDynamicBuffer->fBitArray[index]==NULL)
336                                        continue;
337                                for(XMLSize_t subIndex=0;subIndex < CMSTATE_BITFIELD_INT32_SIZE; subIndex++)
338                                {
339                                        if (fDynamicBuffer->fBitArray[index][subIndex] != 0)
340                                                for(int i=0;i<32;i++)
341                                                {
342                                                        const XMLInt32 mask = 1UL << i;
343                                                        if(fDynamicBuffer->fBitArray[index][subIndex] & mask)
344                                                                count++;
345                                                }
346                                }
347                        }
348                }
349                return count;
350        }
351
352        bool getBit(const XMLSize_t bitToGet) const
353        {
354                if (bitToGet >= fBitCount)
355                {
356                        if(fDynamicBuffer)
357                                ThrowXMLwithMemMgr(ArrayIndexOutOfBoundsException, XMLExcepts::Bitset_BadIndex, fDynamicBuffer->fMemoryManager);
358                        else
359                                ThrowXML(ArrayIndexOutOfBoundsException, XMLExcepts::Bitset_BadIndex);
360                }
361
362                // And access the right bit and byte
363                if(fDynamicBuffer==0)
364                {
365                        const XMLInt32 mask = 1UL << (bitToGet % 32);
366                        const XMLSize_t byteOfs = bitToGet / 32;
367                        return (fBits[byteOfs]!=0 && (fBits[byteOfs] & mask) != 0);
368                }
369                else
370                {
371                        const XMLSize_t vectorOfs = bitToGet / CMSTATE_BITFIELD_CHUNK;
372                        if(fDynamicBuffer->fBitArray[vectorOfs]==NULL)
373                                return false;
374                        const XMLInt32 mask = 1UL << (bitToGet % 32);
375                        const XMLSize_t byteOfs = (bitToGet % CMSTATE_BITFIELD_CHUNK) / 32;
376                        return (fDynamicBuffer->fBitArray[vectorOfs][byteOfs]!=0 && (fDynamicBuffer->fBitArray[vectorOfs][byteOfs] & mask) != 0);
377                }
378        }
379
380        bool isEmpty() const
381        {
382                if(fDynamicBuffer==0)
383                {
384                        for (XMLSize_t index = 0; index < CMSTATE_CACHED_INT32_SIZE; index++)
385                        {
386                                if (fBits[index] != 0)
387                                        return false;
388                        }
389                }
390                else
391                {
392                        for (XMLSize_t index = 0; index < fDynamicBuffer->fArraySize; index++)
393                        {
394                                if(fDynamicBuffer->fBitArray[index]==NULL)
395                                        continue;
396                                for(XMLSize_t subIndex=0;subIndex < CMSTATE_BITFIELD_INT32_SIZE; subIndex++)
397                                {
398                                        if (fDynamicBuffer->fBitArray[index][subIndex] != 0)
399                                                return false;
400                                }
401                        }
402                }
403                return true;
404        }
405
406        void setBit(const XMLSize_t bitToSet)
407        {
408                if (bitToSet >= fBitCount)
409                {
410                        if(fDynamicBuffer)
411                                ThrowXMLwithMemMgr(ArrayIndexOutOfBoundsException, XMLExcepts::Bitset_BadIndex, fDynamicBuffer->fMemoryManager);
412                        else
413                                ThrowXML(ArrayIndexOutOfBoundsException, XMLExcepts::Bitset_BadIndex);
414                }
415
416                const XMLInt32 mask = 1UL << (bitToSet % 32);
417
418                // And access the right bit and byte
419                if(fDynamicBuffer==0)
420                {
421                        const XMLSize_t byteOfs = bitToSet / 32;
422                        fBits[byteOfs] &= ~mask;
423                        fBits[byteOfs] |= mask;
424                }
425                else
426                {
427                        const XMLSize_t vectorOfs = bitToSet / CMSTATE_BITFIELD_CHUNK;
428                        if(fDynamicBuffer->fBitArray[vectorOfs]==NULL)
429                        {
430                                allocateChunk(vectorOfs);
431                                for(XMLSize_t index=0;index < CMSTATE_BITFIELD_INT32_SIZE; index++)
432                                        fDynamicBuffer->fBitArray[vectorOfs][index]=0;
433                        }
434                        const XMLSize_t byteOfs = (bitToSet % CMSTATE_BITFIELD_CHUNK) / 32;
435                        fDynamicBuffer->fBitArray[vectorOfs][byteOfs] &= ~mask;
436                        fDynamicBuffer->fBitArray[vectorOfs][byteOfs] |= mask;
437                }
438        }
439
440        void zeroBits()
441        {
442                if(fDynamicBuffer==0)
443                {
444                        for (XMLSize_t index = 0; index < CMSTATE_CACHED_INT32_SIZE; index++)
445                                fBits[index] = 0;
446                }
447                else
448                {
449                        for (XMLSize_t index = 0; index < fDynamicBuffer->fArraySize; index++)
450                                // delete this subentry
451                                if(fDynamicBuffer->fBitArray[index]!=NULL)
452                                        deallocateChunk(index);
453                }
454        }
455
456        XMLSize_t hashCode() const
457        {
458                XMLSize_t hash = 0;
459                if(fDynamicBuffer==0)
460                {
461                        for (XMLSize_t index = 0; index<CMSTATE_CACHED_INT32_SIZE; index++)
462                                hash = fBits[index] + hash * 31;
463                }
464                else
465                {
466                        for (XMLSize_t index = 0; index<fDynamicBuffer->fArraySize; index++)
467                        {
468                                if(fDynamicBuffer->fBitArray[index]==NULL)
469                                        // simulates the iteration on the missing bits
470                                        for(XMLSize_t subIndex=0;subIndex < CMSTATE_BITFIELD_INT32_SIZE; subIndex++)
471                                                hash *= 31;
472                                else
473                                        for(XMLSize_t subIndex=0;subIndex < CMSTATE_BITFIELD_INT32_SIZE; subIndex++)
474                                                hash = fDynamicBuffer->fBitArray[index][subIndex] + hash * 31;
475                        }
476                }
477                return hash;
478        }
479
480private :
481        // -----------------------------------------------------------------------
482        //  Unimplemented constructors and operators
483        // -----------------------------------------------------------------------
484        CMStateSet();
485
486        // -----------------------------------------------------------------------
487        // Helpers
488        // -----------------------------------------------------------------------
489        void allocateChunk(const XMLSize_t index)
490        {
491#ifdef XERCES_HAVE_SSE2_INTRINSIC
492                if(XMLPlatformUtils::fgSSE2ok)
493                        fDynamicBuffer->fBitArray[index]=(XMLInt32*)_mm_malloc(CMSTATE_BITFIELD_INT32_SIZE * sizeof(XMLInt32), 16);
494                else
495#endif
496                        fDynamicBuffer->fBitArray[index]=(XMLInt32*)fDynamicBuffer->fMemoryManager->allocate(CMSTATE_BITFIELD_INT32_SIZE * sizeof(XMLInt32));
497        }
498
499        void deallocateChunk(const XMLSize_t index)
500        {
501#ifdef XERCES_HAVE_SSE2_INTRINSIC
502                if(XMLPlatformUtils::fgSSE2ok)
503                        _mm_free(fDynamicBuffer->fBitArray[index]);
504                else
505#endif
506                        fDynamicBuffer->fMemoryManager->deallocate(fDynamicBuffer->fBitArray[index]);
507                fDynamicBuffer->fBitArray[index]=NULL;
508        }
509
510        // -----------------------------------------------------------------------
511        //  Private data members
512        //
513        //  fBitCount
514        //      The count of bits that the outside world wants to support,
515        //      so its the max bit index plus one.
516        //
517        //  fBits
518        //      When the bit count is less than a threshold (very common), these hold the bits.
519        //      Otherwise, the fDynamicBuffer member holds htem.
520        //
521        //  fDynamicBuffer
522        //      If the bit count is greater than the threshold, then we allocate this structure to
523        //      store the bits, the length, and the memory manager to allocate/deallocate
524        //      the memory
525        //
526        // -----------------------------------------------------------------------
527        XMLSize_t        fBitCount;
528        XMLInt32         fBits[CMSTATE_CACHED_INT32_SIZE];
529        CMDynamicBuffer* fDynamicBuffer;
530
531        friend class CMStateSetEnumerator;
532};
533
534class CMStateSetEnumerator : public XMemory
535{
536public:
537        CMStateSetEnumerator(const CMStateSet* toEnum, XMLSize_t start = 0) :
538          fToEnum(toEnum),
539          fIndexCount((XMLSize_t)-1),
540          fLastValue(0)
541        {
542                // if a starting bit is specified, place fIndexCount at the beginning of the previous 32 bit area
543                // so the findNext moves to the one where 'start' is located
544                if(start > 32)
545                        fIndexCount = (start/32 - 1) * 32;
546                findNext();
547                // if we found data, and fIndexCount is still pointing to the area where 'start' is located, erase the bits before 'start'
548                if(hasMoreElements() && fIndexCount < start)
549                {
550                        for(XMLSize_t i=0;i< (start - fIndexCount);i++)
551                        {
552                                XMLInt32 mask=1UL << i;
553                                if(fLastValue & mask)
554                                        fLastValue &= ~mask;
555                        }
556                        // in case the 32 bit area contained only bits before 'start', advance
557                        if(fLastValue==0)
558                                findNext();
559                }
560        }
561
562        bool hasMoreElements()
563        {
564                return fLastValue!=0;
565        }
566
567        unsigned int nextElement()
568        {
569                for(int i=0;i<32;i++)
570                {
571                        XMLInt32 mask=1UL << i;
572                        if(fLastValue & mask)
573                        {
574                                fLastValue &= ~mask;
575                                unsigned int retVal=(unsigned int)fIndexCount+i;
576                                if(fLastValue==0)
577                                        findNext();
578                                return retVal;
579                        }
580                }
581                return 0;
582        }
583
584private:
585        void findNext()
586        {
587                if(fToEnum->fDynamicBuffer==0)
588                {
589                        XMLSize_t nOffset=((fIndexCount==(XMLSize_t)-1)?0:(fIndexCount/32)+1);
590                        for(XMLSize_t index=nOffset;index<CMSTATE_CACHED_INT32_SIZE;index++)
591                        {
592                                if(fToEnum->fBits[index]!=0)
593                                {
594                                        fIndexCount=index*32;
595                                        fLastValue=fToEnum->fBits[index];
596                                        return;
597                                }
598                        }
599                }
600                else
601                {
602                        XMLSize_t nOffset=((fIndexCount==(XMLSize_t)-1)?0:(fIndexCount/CMSTATE_BITFIELD_CHUNK));
603                        XMLSize_t nSubOffset=((fIndexCount==(XMLSize_t)-1)?0:((fIndexCount % CMSTATE_BITFIELD_CHUNK) /32)+1);
604                        for (XMLSize_t index = nOffset; index<fToEnum->fDynamicBuffer->fArraySize; index++)
605                        {
606                                if(fToEnum->fDynamicBuffer->fBitArray[index]!=NULL)
607                                {
608                                        for(XMLSize_t subIndex=nSubOffset;subIndex < CMSTATE_BITFIELD_INT32_SIZE; subIndex++)
609                                                if(fToEnum->fDynamicBuffer->fBitArray[index][subIndex]!=0)
610                                                {
611                                                        fIndexCount=index*CMSTATE_BITFIELD_CHUNK + subIndex*32;
612                                                        fLastValue=fToEnum->fDynamicBuffer->fBitArray[index][subIndex];
613                                                        return;
614                                                }
615                                }
616                                nSubOffset = 0; // next chunks will be processed from the beginning
617                        }
618                }
619        }
620
621        const CMStateSet*   fToEnum;
622        XMLSize_t           fIndexCount;
623        XMLInt32            fLastValue;
624};
625
626XERCES_CPP_NAMESPACE_END
627
628#endif
Note: See TracBrowser for help on using the repository browser.