/* * Licensed to the Apache Software Foundation (ASF) under one or more * contributor license agreements. See the NOTICE file distributed with * this work for additional information regarding copyright ownership. * The ASF licenses this file to You under the Apache License, Version 2.0 * (the "License"); you may not use this file except in compliance with * the License. You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ /* * $Id$ */ // --------------------------------------------------------------------------- // Includes // --------------------------------------------------------------------------- #include #include XERCES_CPP_NAMESPACE_BEGIN // --------------------------------------------------------------------------- // Local const data // // kBitsPerUnit // The number of bits in each of our allocation units, which is a 32 // bit value in this case. // // kGrowBy // The minimum allocation units to grow the buffer by. // --------------------------------------------------------------------------- const XMLSize_t kBitsPerUnit = 32; const XMLSize_t kGrowBy = 1; // --------------------------------------------------------------------------- // BitSet: Constructors and Destructor // --------------------------------------------------------------------------- BitSet::BitSet( const XMLSize_t size , MemoryManager* const manager) : fMemoryManager(manager) , fBits(0) , fUnitLen(0) { ensureCapacity(size); } BitSet::BitSet(const BitSet& toCopy) : XMemory(toCopy) , fMemoryManager(toCopy.fMemoryManager) , fBits(0) , fUnitLen(toCopy.fUnitLen) { fBits = (unsigned long*) fMemoryManager->allocate ( fUnitLen * sizeof(unsigned long) ); //new unsigned long[fUnitLen]; for (XMLSize_t i = 0; i < fUnitLen; i++) fBits[i] = toCopy.fBits[i]; } BitSet::~BitSet() { fMemoryManager->deallocate(fBits); //delete [] fBits; } // --------------------------------------------------------------------------- // BitSet: Equality methods // --------------------------------------------------------------------------- bool BitSet::equals(const BitSet& other) const { if (this == &other) return true; if (fUnitLen != other.fUnitLen) return false; for (XMLSize_t i = 0; i < fUnitLen; i++) { if (fBits[i] != other.fBits[i]) return false; } return true; } // --------------------------------------------------------------------------- // BitSet: Getter methods // --------------------------------------------------------------------------- bool BitSet::get(const XMLSize_t index) const { const XMLSize_t unitOfBit = (index / kBitsPerUnit); const XMLSize_t bitWithinUnit = index % kBitsPerUnit; // // If the index is beyond our size, don't actually expand. Just return // false, which is what the state would be if we did expand it. // bool retVal = false; if (unitOfBit <= fUnitLen) { if (fBits[unitOfBit] & (1 << bitWithinUnit)) retVal = true; } return retVal; } XMLSize_t BitSet::size() const { return fUnitLen * kBitsPerUnit; } // --------------------------------------------------------------------------- // BitSet: Setter methods // --------------------------------------------------------------------------- bool BitSet::allAreCleared() const { for (XMLSize_t index = 0; index < fUnitLen; index++) { if (fBits[index]) return false; } return true; } bool BitSet::allAreSet() const { for (XMLSize_t index = 0; index < fUnitLen; index++) { if (fBits[index] != 0xFFFFFFFF) return false; } return true; } void BitSet::clearAll() { // Just zero out all the units for (XMLSize_t index = 0; index < fUnitLen; index++) fBits[index] = 0; } void BitSet::clear(const XMLSize_t index) { ensureCapacity(index+1); const XMLSize_t unitOfBit = (index / kBitsPerUnit); const XMLSize_t bitWithinUnit = index % kBitsPerUnit; fBits[unitOfBit] &= ~(1UL << bitWithinUnit); } void BitSet::set(const XMLSize_t index) { ensureCapacity(index+1); const XMLSize_t unitOfBit = (index / kBitsPerUnit); const XMLSize_t bitWithinUnit = index % kBitsPerUnit; fBits[unitOfBit] |= (1UL << bitWithinUnit); } // --------------------------------------------------------------------------- // BitSet: Bitwise logical methods // --------------------------------------------------------------------------- void BitSet::andWith(const BitSet& other) { if (fUnitLen < other.fUnitLen) ensureCapacity(other.fUnitLen * kBitsPerUnit); for (XMLSize_t index = 0; index < other.fUnitLen; index++) fBits[index] &= other.fBits[index]; } void BitSet::orWith(const BitSet& other) { if (fUnitLen < other.fUnitLen) ensureCapacity(other.fUnitLen * kBitsPerUnit); for (XMLSize_t index = 0; index < other.fUnitLen; index++) fBits[index] |= other.fBits[index]; } void BitSet::xorWith(const BitSet& other) { if (fUnitLen < other.fUnitLen) ensureCapacity(other.fUnitLen * kBitsPerUnit); for (XMLSize_t index = 0; index < other.fUnitLen; index++) fBits[index] ^= other.fBits[index]; } // --------------------------------------------------------------------------- // BitSet: Miscellaneous methods // --------------------------------------------------------------------------- XMLSize_t BitSet::hash(const XMLSize_t hashModulus) const { const unsigned char* pBytes = (const unsigned char*)fBits; const XMLSize_t len = fUnitLen * sizeof(unsigned long); XMLSize_t hashVal = 0; for (XMLSize_t index = 0; index < len; index++) { hashVal <<= 1; hashVal ^= *pBytes; } return hashVal % hashModulus; } // --------------------------------------------------------------------------- // BitSet: Private methods // --------------------------------------------------------------------------- void BitSet::ensureCapacity(const XMLSize_t size) { // If we have enough space, do nothing if(fUnitLen * kBitsPerUnit >= size) return; // Calculate the units required to hold the passed bit count. XMLSize_t unitsNeeded = size / kBitsPerUnit; if (size % kBitsPerUnit) unitsNeeded++; // Regrow the unit length by at least the expansion unit if (unitsNeeded < (fUnitLen + kGrowBy)) unitsNeeded = fUnitLen + kGrowBy; // Allocate the array, copy the old stuff, and zero the new stuff unsigned long* newBits = (unsigned long*) fMemoryManager->allocate ( unitsNeeded * sizeof(unsigned long) ); //new unsigned long[unitsNeeded]; XMLSize_t index; for (index = 0; index < fUnitLen; index++) newBits[index] = fBits[index]; for (; index < unitsNeeded; index++) newBits[index] = 0; fMemoryManager->deallocate(fBits); //delete [] fBits; fBits = newBits; fUnitLen = unitsNeeded; } XERCES_CPP_NAMESPACE_END