File indexing completed on 2025-12-17 10:31:17
0001
0002
0003
0004
0005
0006
0007
0008
0009
0010
0011
0012
0013
0014
0015
0016
0017
0018
0019
0020
0021
0022 #if !defined(XERCESC_INCLUDE_GUARD_CMSTATESET_HPP)
0023 #define XERCESC_INCLUDE_GUARD_CMSTATESET_HPP
0024
0025
0026
0027
0028
0029
0030
0031
0032
0033
0034 #include <xercesc/util/ArrayIndexOutOfBoundsException.hpp>
0035 #include <xercesc/util/OutOfMemoryException.hpp>
0036 #include <xercesc/util/RuntimeException.hpp>
0037 #include <xercesc/util/PlatformUtils.hpp>
0038 #include <xercesc/framework/MemoryManager.hpp>
0039 #include <string.h>
0040
0041 #if XERCES_HAVE_EMMINTRIN_H
0042 # include <emmintrin.h>
0043 #endif
0044
0045 XERCES_CPP_NAMESPACE_BEGIN
0046
0047 class CMStateSetEnumerator;
0048
0049
0050 #define CMSTATE_CACHED_INT32_SIZE 4
0051
0052
0053 #define CMSTATE_BITFIELD_CHUNK 1024
0054 #define CMSTATE_BITFIELD_INT32_SIZE (1024 / 32)
0055
0056 struct CMDynamicBuffer
0057 {
0058
0059
0060
0061
0062
0063
0064
0065
0066
0067
0068 XMLSize_t fArraySize;
0069 XMLInt32** fBitArray;
0070 MemoryManager* fMemoryManager;
0071 };
0072
0073 class CMStateSet : public XMemory
0074 {
0075 public :
0076
0077
0078
0079 CMStateSet( const XMLSize_t bitCount
0080 , MemoryManager* const manager = XMLPlatformUtils::fgMemoryManager) :
0081
0082 fBitCount(bitCount)
0083 , fDynamicBuffer(0)
0084 {
0085
0086
0087
0088
0089 if (fBitCount > (CMSTATE_CACHED_INT32_SIZE * 32))
0090 {
0091 fDynamicBuffer = (CMDynamicBuffer*)manager->allocate(sizeof(CMDynamicBuffer));
0092 fDynamicBuffer->fMemoryManager = manager;
0093
0094 fDynamicBuffer->fArraySize = fBitCount / CMSTATE_BITFIELD_CHUNK;
0095 if (fBitCount % CMSTATE_BITFIELD_CHUNK)
0096 fDynamicBuffer->fArraySize++;
0097 try
0098 {
0099 fDynamicBuffer->fBitArray = (XMLInt32**) fDynamicBuffer->fMemoryManager->allocate(fDynamicBuffer->fArraySize*sizeof(XMLInt32*));
0100 }
0101 catch( const OutOfMemoryException& )
0102 {
0103 fDynamicBuffer->fMemoryManager->deallocate(fDynamicBuffer);
0104 throw;
0105 }
0106 for(XMLSize_t index = 0; index < fDynamicBuffer->fArraySize; index++)
0107 fDynamicBuffer->fBitArray[index]=NULL;
0108 }
0109 else
0110 {
0111 for (XMLSize_t index = 0; index < CMSTATE_CACHED_INT32_SIZE; index++)
0112 fBits[index] = 0;
0113 }
0114 }
0115
0116 CMStateSet(const CMStateSet& toCopy) :
0117 XMemory(toCopy)
0118 , fBitCount(toCopy.fBitCount)
0119 , fDynamicBuffer(0)
0120 {
0121
0122
0123
0124
0125 if (fBitCount > (CMSTATE_CACHED_INT32_SIZE * 32))
0126 {
0127 fDynamicBuffer = (CMDynamicBuffer*) toCopy.fDynamicBuffer->fMemoryManager->allocate(sizeof(CMDynamicBuffer));
0128 fDynamicBuffer->fMemoryManager = toCopy.fDynamicBuffer->fMemoryManager;
0129 fDynamicBuffer->fArraySize = fBitCount / CMSTATE_BITFIELD_CHUNK;
0130 if (fBitCount % CMSTATE_BITFIELD_CHUNK)
0131 fDynamicBuffer->fArraySize++;
0132 fDynamicBuffer->fBitArray = (XMLInt32**) fDynamicBuffer->fMemoryManager->allocate(fDynamicBuffer->fArraySize*sizeof(XMLInt32*));
0133 for(XMLSize_t index = 0; index < fDynamicBuffer->fArraySize; index++)
0134 {
0135 if(toCopy.fDynamicBuffer->fBitArray[index]!=NULL)
0136 {
0137 allocateChunk(index);
0138 memcpy((void *) fDynamicBuffer->fBitArray[index],
0139 (const void *) toCopy.fDynamicBuffer->fBitArray[index],
0140 CMSTATE_BITFIELD_INT32_SIZE * sizeof(XMLInt32));
0141 }
0142 else
0143 fDynamicBuffer->fBitArray[index]=NULL;
0144 }
0145 }
0146 else
0147 {
0148 memcpy((void *) fBits,
0149 (const void *) toCopy.fBits,
0150 CMSTATE_CACHED_INT32_SIZE * sizeof(XMLInt32));
0151 }
0152 }
0153
0154 ~CMStateSet()
0155 {
0156 if(fDynamicBuffer)
0157 {
0158 for(XMLSize_t index = 0; index < fDynamicBuffer->fArraySize; index++)
0159 if(fDynamicBuffer->fBitArray[index]!=NULL)
0160 deallocateChunk(index);
0161 fDynamicBuffer->fMemoryManager->deallocate(fDynamicBuffer->fBitArray);
0162 fDynamicBuffer->fMemoryManager->deallocate(fDynamicBuffer);
0163 }
0164 }
0165
0166
0167
0168
0169
0170 void operator|=(const CMStateSet& setToOr)
0171 {
0172 if(fDynamicBuffer==0)
0173 {
0174 #ifdef XERCES_HAVE_SSE2_INTRINSIC
0175 if(XMLPlatformUtils::fgSSE2ok)
0176 {
0177 __m128i xmm1 = _mm_loadu_si128(reinterpret_cast<const __m128i*>(fBits));
0178 __m128i xmm2 = _mm_loadu_si128(reinterpret_cast<const __m128i*>(setToOr.fBits));
0179 __m128i xmm3 = _mm_or_si128(xmm1, xmm2);
0180 _mm_storeu_si128(reinterpret_cast<__m128i*>(fBits), xmm3);
0181 }
0182 else
0183 #endif
0184 {
0185 for (XMLSize_t index = 0; index < CMSTATE_CACHED_INT32_SIZE; index++)
0186 if(setToOr.fBits[index])
0187 {
0188 if(fBits[index])
0189 fBits[index] |= setToOr.fBits[index];
0190 else
0191 fBits[index] = setToOr.fBits[index];
0192 }
0193 }
0194 }
0195 else
0196 {
0197 for (XMLSize_t index = 0; index < fDynamicBuffer->fArraySize; index++)
0198 {
0199 XMLInt32 *& other = setToOr.fDynamicBuffer->fBitArray[index];
0200 if(other!=NULL)
0201 {
0202
0203 if(fDynamicBuffer->fBitArray[index]==NULL)
0204 {
0205 allocateChunk(index);
0206 memcpy((void *) fDynamicBuffer->fBitArray[index],
0207 (const void *) other,
0208 CMSTATE_BITFIELD_INT32_SIZE * sizeof(XMLInt32));
0209 }
0210 else
0211 {
0212
0213 XMLInt32*& mine = fDynamicBuffer->fBitArray[index];
0214 #ifdef XERCES_HAVE_SSE2_INTRINSIC
0215 if(XMLPlatformUtils::fgSSE2ok)
0216 {
0217 for(XMLSize_t subIndex = 0; subIndex < CMSTATE_BITFIELD_INT32_SIZE; subIndex+=4)
0218 {
0219 __m128i xmm1 = _mm_load_si128(reinterpret_cast<const __m128i*>(&other[subIndex]));
0220 __m128i xmm2 = _mm_load_si128(reinterpret_cast<const __m128i*>(&mine[subIndex]));
0221 __m128i xmm3 = _mm_or_si128(xmm1, xmm2);
0222 _mm_store_si128(reinterpret_cast<__m128i*>(&mine[subIndex]), xmm3);
0223 }
0224 }
0225 else
0226 #endif
0227 {
0228 for(XMLSize_t subIndex = 0; subIndex < CMSTATE_BITFIELD_INT32_SIZE; subIndex++)
0229 if(setToOr.fDynamicBuffer->fBitArray[index][subIndex])
0230 {
0231 if(fDynamicBuffer->fBitArray[index][subIndex])
0232 fDynamicBuffer->fBitArray[index][subIndex] |= setToOr.fDynamicBuffer->fBitArray[index][subIndex];
0233 else
0234 fDynamicBuffer->fBitArray[index][subIndex] = setToOr.fDynamicBuffer->fBitArray[index][subIndex];
0235 }
0236 }
0237 }
0238 }
0239 }
0240 }
0241 }
0242
0243 bool operator==(const CMStateSet& setToCompare) const
0244 {
0245 if (fBitCount != setToCompare.fBitCount)
0246 return false;
0247
0248 if(fDynamicBuffer==0)
0249 {
0250 for (XMLSize_t index = 0; index < CMSTATE_CACHED_INT32_SIZE; index++)
0251 {
0252 if (fBits[index] != setToCompare.fBits[index])
0253 return false;
0254 }
0255 }
0256 else
0257 {
0258 for (XMLSize_t index = 0; index < fDynamicBuffer->fArraySize; index++)
0259 {
0260 XMLInt32 *& other = setToCompare.fDynamicBuffer->fBitArray[index],
0261 *& mine = fDynamicBuffer->fBitArray[index];
0262 if(mine==NULL && other==NULL)
0263 continue;
0264 else if(mine==NULL || other==NULL)
0265 return false;
0266 else
0267 {
0268 for(XMLSize_t subIndex = 0; subIndex < CMSTATE_BITFIELD_INT32_SIZE; subIndex++)
0269 if(mine[subIndex]!=other[subIndex])
0270 return false;
0271 }
0272 }
0273 }
0274 return true;
0275 }
0276
0277 CMStateSet& operator=(const CMStateSet& srcSet)
0278 {
0279 if (this == &srcSet)
0280 return *this;
0281
0282
0283 if (fBitCount != srcSet.fBitCount)
0284 {
0285 if(fDynamicBuffer)
0286 ThrowXMLwithMemMgr(RuntimeException, XMLExcepts::Bitset_NotEqualSize, fDynamicBuffer->fMemoryManager);
0287 else
0288 ThrowXML(RuntimeException, XMLExcepts::Bitset_NotEqualSize);
0289 }
0290
0291 if(fDynamicBuffer==0)
0292 {
0293 for (XMLSize_t index = 0; index < CMSTATE_CACHED_INT32_SIZE; index++)
0294 fBits[index] = srcSet.fBits[index];
0295 }
0296 else
0297 {
0298 for (XMLSize_t index = 0; index < fDynamicBuffer->fArraySize; index++)
0299 if(srcSet.fDynamicBuffer->fBitArray[index]==NULL)
0300 {
0301
0302 if(fDynamicBuffer->fBitArray[index]!=NULL)
0303 deallocateChunk(index);
0304 }
0305 else
0306 {
0307
0308 if(fDynamicBuffer->fBitArray[index]==NULL)
0309 allocateChunk(index);
0310 memcpy((void *) fDynamicBuffer->fBitArray[index],
0311 (const void *) srcSet.fDynamicBuffer->fBitArray[index],
0312 CMSTATE_BITFIELD_INT32_SIZE * sizeof(XMLInt32));
0313 }
0314 }
0315 return *this;
0316 }
0317
0318 XMLSize_t getBitCountInRange(XMLSize_t start, XMLSize_t end) const
0319 {
0320 XMLSize_t count = 0;
0321 end /= 32;
0322 if(fDynamicBuffer==0)
0323 {
0324 if(end > CMSTATE_CACHED_INT32_SIZE)
0325 end = CMSTATE_CACHED_INT32_SIZE;
0326 for (XMLSize_t index = start / 32; index < end; index++)
0327 {
0328 if (fBits[index] != 0)
0329 for(int i=0;i<32;i++)
0330 {
0331 const XMLInt32 mask = 1UL << i;
0332 if(fBits[index] & mask)
0333 count++;
0334 }
0335 }
0336 }
0337 else
0338 {
0339 if(end > fDynamicBuffer->fArraySize)
0340 end = fDynamicBuffer->fArraySize;
0341 for (XMLSize_t index = start / 32; index < end; index++)
0342 {
0343 if(fDynamicBuffer->fBitArray[index]==NULL)
0344 continue;
0345 for(XMLSize_t subIndex=0;subIndex < CMSTATE_BITFIELD_INT32_SIZE; subIndex++)
0346 {
0347 if (fDynamicBuffer->fBitArray[index][subIndex] != 0)
0348 for(int i=0;i<32;i++)
0349 {
0350 const XMLInt32 mask = 1UL << i;
0351 if(fDynamicBuffer->fBitArray[index][subIndex] & mask)
0352 count++;
0353 }
0354 }
0355 }
0356 }
0357 return count;
0358 }
0359
0360 bool getBit(const XMLSize_t bitToGet) const
0361 {
0362 if (bitToGet >= fBitCount)
0363 {
0364 if(fDynamicBuffer)
0365 ThrowXMLwithMemMgr(ArrayIndexOutOfBoundsException, XMLExcepts::Bitset_BadIndex, fDynamicBuffer->fMemoryManager);
0366 else
0367 ThrowXML(ArrayIndexOutOfBoundsException, XMLExcepts::Bitset_BadIndex);
0368 }
0369
0370
0371 if(fDynamicBuffer==0)
0372 {
0373 const XMLInt32 mask = 1UL << (bitToGet % 32);
0374 const XMLSize_t byteOfs = bitToGet / 32;
0375 return (fBits[byteOfs]!=0 && (fBits[byteOfs] & mask) != 0);
0376 }
0377 else
0378 {
0379 const XMLSize_t vectorOfs = bitToGet / CMSTATE_BITFIELD_CHUNK;
0380 if(fDynamicBuffer->fBitArray[vectorOfs]==NULL)
0381 return false;
0382 const XMLInt32 mask = 1UL << (bitToGet % 32);
0383 const XMLSize_t byteOfs = (bitToGet % CMSTATE_BITFIELD_CHUNK) / 32;
0384 return (fDynamicBuffer->fBitArray[vectorOfs][byteOfs]!=0 && (fDynamicBuffer->fBitArray[vectorOfs][byteOfs] & mask) != 0);
0385 }
0386 }
0387
0388 bool isEmpty() const
0389 {
0390 if(fDynamicBuffer==0)
0391 {
0392 for (XMLSize_t index = 0; index < CMSTATE_CACHED_INT32_SIZE; index++)
0393 {
0394 if (fBits[index] != 0)
0395 return false;
0396 }
0397 }
0398 else
0399 {
0400 for (XMLSize_t index = 0; index < fDynamicBuffer->fArraySize; index++)
0401 {
0402 if(fDynamicBuffer->fBitArray[index]==NULL)
0403 continue;
0404 for(XMLSize_t subIndex=0;subIndex < CMSTATE_BITFIELD_INT32_SIZE; subIndex++)
0405 {
0406 if (fDynamicBuffer->fBitArray[index][subIndex] != 0)
0407 return false;
0408 }
0409 }
0410 }
0411 return true;
0412 }
0413
0414 void setBit(const XMLSize_t bitToSet)
0415 {
0416 if (bitToSet >= fBitCount)
0417 {
0418 if(fDynamicBuffer)
0419 ThrowXMLwithMemMgr(ArrayIndexOutOfBoundsException, XMLExcepts::Bitset_BadIndex, fDynamicBuffer->fMemoryManager);
0420 else
0421 ThrowXML(ArrayIndexOutOfBoundsException, XMLExcepts::Bitset_BadIndex);
0422 }
0423
0424 const XMLInt32 mask = 1UL << (bitToSet % 32);
0425
0426
0427 if(fDynamicBuffer==0)
0428 {
0429 const XMLSize_t byteOfs = bitToSet / 32;
0430 fBits[byteOfs] &= ~mask;
0431 fBits[byteOfs] |= mask;
0432 }
0433 else
0434 {
0435 const XMLSize_t vectorOfs = bitToSet / CMSTATE_BITFIELD_CHUNK;
0436 if(fDynamicBuffer->fBitArray[vectorOfs]==NULL)
0437 {
0438 allocateChunk(vectorOfs);
0439 for(XMLSize_t index=0;index < CMSTATE_BITFIELD_INT32_SIZE; index++)
0440 fDynamicBuffer->fBitArray[vectorOfs][index]=0;
0441 }
0442 const XMLSize_t byteOfs = (bitToSet % CMSTATE_BITFIELD_CHUNK) / 32;
0443 fDynamicBuffer->fBitArray[vectorOfs][byteOfs] &= ~mask;
0444 fDynamicBuffer->fBitArray[vectorOfs][byteOfs] |= mask;
0445 }
0446 }
0447
0448 void zeroBits()
0449 {
0450 if(fDynamicBuffer==0)
0451 {
0452 for (XMLSize_t index = 0; index < CMSTATE_CACHED_INT32_SIZE; index++)
0453 fBits[index] = 0;
0454 }
0455 else
0456 {
0457 for (XMLSize_t index = 0; index < fDynamicBuffer->fArraySize; index++)
0458
0459 if(fDynamicBuffer->fBitArray[index]!=NULL)
0460 deallocateChunk(index);
0461 }
0462 }
0463
0464 XMLSize_t hashCode() const
0465 {
0466 XMLSize_t hash = 0;
0467 if(fDynamicBuffer==0)
0468 {
0469 for (XMLSize_t index = 0; index<CMSTATE_CACHED_INT32_SIZE; index++)
0470 hash = fBits[index] + hash * 31;
0471 }
0472 else
0473 {
0474 for (XMLSize_t index = 0; index<fDynamicBuffer->fArraySize; index++)
0475 {
0476 if(fDynamicBuffer->fBitArray[index]==NULL)
0477
0478 for(XMLSize_t subIndex=0;subIndex < CMSTATE_BITFIELD_INT32_SIZE; subIndex++)
0479 hash *= 31;
0480 else
0481 for(XMLSize_t subIndex=0;subIndex < CMSTATE_BITFIELD_INT32_SIZE; subIndex++)
0482 hash = fDynamicBuffer->fBitArray[index][subIndex] + hash * 31;
0483 }
0484 }
0485 return hash;
0486 }
0487
0488 private :
0489
0490
0491
0492 CMStateSet();
0493
0494
0495
0496
0497 void allocateChunk(const XMLSize_t index)
0498 {
0499 #ifdef XERCES_HAVE_SSE2_INTRINSIC
0500 if(XMLPlatformUtils::fgSSE2ok)
0501 fDynamicBuffer->fBitArray[index]=(XMLInt32*)_mm_malloc(CMSTATE_BITFIELD_INT32_SIZE * sizeof(XMLInt32), 16);
0502 else
0503 #endif
0504 fDynamicBuffer->fBitArray[index]=(XMLInt32*)fDynamicBuffer->fMemoryManager->allocate(CMSTATE_BITFIELD_INT32_SIZE * sizeof(XMLInt32));
0505 }
0506
0507 void deallocateChunk(const XMLSize_t index)
0508 {
0509 #ifdef XERCES_HAVE_SSE2_INTRINSIC
0510 if(XMLPlatformUtils::fgSSE2ok)
0511 _mm_free(fDynamicBuffer->fBitArray[index]);
0512 else
0513 #endif
0514 fDynamicBuffer->fMemoryManager->deallocate(fDynamicBuffer->fBitArray[index]);
0515 fDynamicBuffer->fBitArray[index]=NULL;
0516 }
0517
0518
0519
0520
0521
0522
0523
0524
0525
0526
0527
0528
0529
0530
0531
0532
0533
0534
0535 XMLSize_t fBitCount;
0536 XMLInt32 fBits[CMSTATE_CACHED_INT32_SIZE];
0537 CMDynamicBuffer* fDynamicBuffer;
0538
0539 friend class CMStateSetEnumerator;
0540 };
0541
0542 class CMStateSetEnumerator : public XMemory
0543 {
0544 public:
0545 CMStateSetEnumerator(const CMStateSet* toEnum, XMLSize_t start = 0) :
0546 fToEnum(toEnum),
0547 fIndexCount((XMLSize_t)-1),
0548 fLastValue(0)
0549 {
0550
0551
0552 if(start > 32)
0553 fIndexCount = (start/32 - 1) * 32;
0554 findNext();
0555
0556 if(hasMoreElements() && fIndexCount < start)
0557 {
0558 for(XMLSize_t i=0;i< (start - fIndexCount);i++)
0559 {
0560 XMLInt32 mask=1UL << i;
0561 if(fLastValue & mask)
0562 fLastValue &= ~mask;
0563 }
0564
0565 if(fLastValue==0)
0566 findNext();
0567 }
0568 }
0569
0570 bool hasMoreElements()
0571 {
0572 return fLastValue!=0;
0573 }
0574
0575 unsigned int nextElement()
0576 {
0577 for(int i=0;i<32;i++)
0578 {
0579 XMLInt32 mask=1UL << i;
0580 if(fLastValue & mask)
0581 {
0582 fLastValue &= ~mask;
0583 unsigned int retVal=(unsigned int)fIndexCount+i;
0584 if(fLastValue==0)
0585 findNext();
0586 return retVal;
0587 }
0588 }
0589 return 0;
0590 }
0591
0592 private:
0593 void findNext()
0594 {
0595 if(fToEnum->fDynamicBuffer==0)
0596 {
0597 XMLSize_t nOffset=((fIndexCount==(XMLSize_t)-1)?0:(fIndexCount/32)+1);
0598 for(XMLSize_t index=nOffset;index<CMSTATE_CACHED_INT32_SIZE;index++)
0599 {
0600 if(fToEnum->fBits[index]!=0)
0601 {
0602 fIndexCount=index*32;
0603 fLastValue=fToEnum->fBits[index];
0604 return;
0605 }
0606 }
0607 }
0608 else
0609 {
0610 XMLSize_t nOffset=((fIndexCount==(XMLSize_t)-1)?0:(fIndexCount/CMSTATE_BITFIELD_CHUNK));
0611 XMLSize_t nSubOffset=((fIndexCount==(XMLSize_t)-1)?0:((fIndexCount % CMSTATE_BITFIELD_CHUNK) /32)+1);
0612 for (XMLSize_t index = nOffset; index<fToEnum->fDynamicBuffer->fArraySize; index++)
0613 {
0614 if(fToEnum->fDynamicBuffer->fBitArray[index]!=NULL)
0615 {
0616 for(XMLSize_t subIndex=nSubOffset;subIndex < CMSTATE_BITFIELD_INT32_SIZE; subIndex++)
0617 if(fToEnum->fDynamicBuffer->fBitArray[index][subIndex]!=0)
0618 {
0619 fIndexCount=index*CMSTATE_BITFIELD_CHUNK + subIndex*32;
0620 fLastValue=fToEnum->fDynamicBuffer->fBitArray[index][subIndex];
0621 return;
0622 }
0623 }
0624 nSubOffset = 0;
0625 }
0626 }
0627 }
0628
0629 const CMStateSet* fToEnum;
0630 XMLSize_t fIndexCount;
0631 XMLInt32 fLastValue;
0632 };
0633
0634 XERCES_CPP_NAMESPACE_END
0635
0636 #endif