1 // [The "BSD licence"] 2 // Copyright (c) 2006-2007 Kay Roepke 2010 Alan Condit 3 // All rights reserved. 4 // 5 // Redistribution and use in source and binary forms, with or without 6 // modification, are permitted provided that the following conditions 7 // are met: 8 // 1. Redistributions of source code must retain the above copyright 9 // notice, this list of conditions and the following disclaimer. 10 // 2. Redistributions in binary form must reproduce the above copyright 11 // notice, this list of conditions and the following disclaimer in the 12 // documentation and/or other materials provided with the distribution. 13 // 3. The name of the author may not be used to endorse or promote products 14 // derived from this software without specific prior written permission. 15 // 16 // THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR 17 // IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES 18 // OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. 19 // IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, 20 // INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT 21 // NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, 22 // DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY 23 // THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT 24 // (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF 25 // THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 26 27 #import "ANTLRBitSet.h" 28 29 @implementation ANTLRBitSet 30 #pragma mark Class Methods 31 32 + (ANTLRBitSet *) newANTLRBitSet 33 { 34 return [[ANTLRBitSet alloc] init]; 35 } 36 37 + (ANTLRBitSet *) newANTLRBitSetWithType:(ANTLRTokenType)type 38 { 39 return [[ANTLRBitSet alloc] initWithType:type]; 40 } 41 42 /** Construct a ANTLRBitSet given the size 43 * @param nbits The size of the ANTLRBitSet in bits 44 */ 45 + (ANTLRBitSet *) newANTLRBitSetWithNBits:(NSUInteger)nbits 46 { 47 return [[ANTLRBitSet alloc] initWithNBits:nbits]; 48 } 49 50 + (ANTLRBitSet *) newANTLRBitSetWithArray:(AMutableArray *)types 51 { 52 return [[ANTLRBitSet alloc] initWithArrayOfBits:types]; 53 } 54 55 + (ANTLRBitSet *) newANTLRBitSetWithBits:(const unsigned long long *)theBits Count:(NSUInteger)longCount 56 { 57 return [[ANTLRBitSet alloc] initWithBits:theBits Count:longCount]; 58 } 59 60 61 + (ANTLRBitSet *) of:(NSUInteger) el 62 { 63 ANTLRBitSet *s = [ANTLRBitSet newANTLRBitSetWithNBits:(el + 1)]; 64 [s add:el]; 65 return s; 66 } 67 68 + (ANTLRBitSet *) of:(NSUInteger) a And2:(NSUInteger) b 69 { 70 NSInteger c = (((a>b)?a:b)+1); 71 ANTLRBitSet *s = [ANTLRBitSet newANTLRBitSetWithNBits:c]; 72 [s add:a]; 73 [s add:b]; 74 return s; 75 } 76 77 + (ANTLRBitSet *) of:(NSUInteger)a And2:(NSUInteger)b And3:(NSUInteger)c 78 { 79 NSUInteger d = ((a>b)?a:b); 80 d = ((c>d)?c:d)+1; 81 ANTLRBitSet *s = [ANTLRBitSet newANTLRBitSetWithNBits:d]; 82 [s add:a]; 83 [s add:b]; 84 [s add:c]; 85 return s; 86 } 87 88 + (ANTLRBitSet *) of:(NSUInteger)a And2:(NSUInteger)b And3:(NSUInteger)c And4:(NSUInteger)d 89 { 90 NSUInteger e = ((a>b)?a:b); 91 NSUInteger f = ((c>d)?c:d); 92 e = ((e>f)?e:f)+1; 93 ANTLRBitSet *s = [ANTLRBitSet newANTLRBitSetWithNBits:e]; 94 [s add:a]; 95 [s add:b]; 96 [s add:c]; 97 [s add:d]; 98 return s; 99 } 100 101 // initializer 102 #pragma mark Initializer 103 104 - (ANTLRBitSet *) init 105 { 106 if ((self = [super init]) != nil) { 107 bitVector = CFBitVectorCreateMutable(kCFAllocatorDefault,0); 108 } 109 return self; 110 } 111 112 - (ANTLRBitSet *) initWithType:(ANTLRTokenType)type 113 { 114 if ((self = [super init]) != nil) { 115 bitVector = CFBitVectorCreateMutable(kCFAllocatorDefault,0); 116 if ((CFIndex)type >= CFBitVectorGetCount(bitVector)) 117 CFBitVectorSetCount(bitVector, type+1); 118 CFBitVectorSetBitAtIndex(bitVector, type, 1); 119 } 120 return self; 121 } 122 123 - (ANTLRBitSet *) initWithNBits:(NSUInteger)nbits 124 { 125 if ((self = [super init]) != nil) { 126 bitVector = CFBitVectorCreateMutable(kCFAllocatorDefault,0); 127 CFBitVectorSetCount( bitVector, nbits ); 128 } 129 return self; 130 } 131 132 - (ANTLRBitSet *) initWithBitVector:(CFMutableBitVectorRef)theBitVector 133 { 134 if ((self = [super init]) != nil) { 135 bitVector = theBitVector; 136 } 137 return self; 138 } 139 140 // Initialize the bit vector with a constant array of ulonglongs like ANTLR generates. 141 // Converts to big endian, because the underlying CFBitVector works like that. 142 - (ANTLRBitSet *) initWithBits:(const unsigned long long *)theBits Count:(NSUInteger)longCount 143 { 144 if ((self = [super init]) != nil) { 145 unsigned int longNo; 146 CFIndex bitIdx; 147 bitVector = CFBitVectorCreateMutable ( kCFAllocatorDefault, 0 ); 148 CFBitVectorSetCount( bitVector, sizeof(unsigned long long)*8*longCount ); 149 150 for (longNo = 0; longNo < longCount; longNo++) { 151 for (bitIdx = 0; bitIdx < (CFIndex)sizeof(unsigned long long)*8; bitIdx++) { 152 unsigned long long swappedBits = CFSwapInt64HostToBig(theBits[longNo]); 153 if (swappedBits & (1LL << bitIdx)) { 154 CFBitVectorSetBitAtIndex(bitVector, bitIdx+(longNo*(sizeof(unsigned long long)*8)), 1); 155 } 156 } 157 } 158 } 159 return self; 160 } 161 162 // Initialize bit vector with an array of anything. Just test the boolValue and set the corresponding bit. 163 // Note: This is big-endian! 164 - (ANTLRBitSet *) initWithArrayOfBits:(NSArray *)theArray 165 { 166 if ((self = [super init]) != nil) { 167 bitVector = CFBitVectorCreateMutable ( kCFAllocatorDefault, 0 ); 168 id value; 169 int bit = 0; 170 for (value in theArray) { 171 if ([value boolValue] == YES) { 172 [self add:bit]; 173 //CFBitVectorSetBitAtIndex(bitVector, bit, 1); 174 } 175 bit++; 176 } 177 } 178 return self; 179 } 180 181 - (void)dealloc 182 { 183 #ifdef DEBUG_DEALLOC 184 NSLog( @"called dealloc in ANTLRBitSet" ); 185 #endif 186 CFRelease(bitVector); 187 [super dealloc]; 188 } 189 190 // operations 191 #pragma mark Operations 192 // return a copy of (self|aBitSet) 193 - (ANTLRBitSet *) or:(ANTLRBitSet *) aBitSet 194 { 195 ANTLRBitSet *bitsetCopy = [self mutableCopyWithZone:nil]; 196 [bitsetCopy orInPlace:aBitSet]; 197 return bitsetCopy; 198 } 199 200 // perform a bitwise OR operation in place by changing underlying bit vector, growing it if necessary 201 - (void) orInPlace:(ANTLRBitSet *) aBitSet 202 { 203 CFIndex selfCnt = CFBitVectorGetCount(bitVector); 204 CFMutableBitVectorRef otherBitVector = [aBitSet _bitVector]; 205 CFIndex otherCnt = CFBitVectorGetCount(otherBitVector); 206 CFIndex maxBitCnt = selfCnt > otherCnt ? selfCnt : otherCnt; 207 CFBitVectorSetCount(bitVector,maxBitCnt); // be sure to grow the CFBitVector manually! 208 209 CFIndex currIdx; 210 for (currIdx = 0; currIdx < maxBitCnt; currIdx++) { 211 if (CFBitVectorGetBitAtIndex(bitVector, currIdx) | CFBitVectorGetBitAtIndex(otherBitVector, currIdx)) { 212 CFBitVectorSetBitAtIndex(bitVector, currIdx, 1); 213 } 214 } 215 } 216 217 // set a bit, grow the bit vector if necessary 218 - (void) add:(NSUInteger) bit 219 { 220 if ((CFIndex)bit >= CFBitVectorGetCount(bitVector)) 221 CFBitVectorSetCount(bitVector, bit+1); 222 CFBitVectorSetBitAtIndex(bitVector, bit, 1); 223 } 224 225 // unset a bit 226 - (void) remove:(NSUInteger) bit 227 { 228 CFBitVectorSetBitAtIndex(bitVector, bit, 0); 229 } 230 231 - (void) setAllBits:(BOOL) aState 232 { 233 for( NSInteger bit=0; bit < CFBitVectorGetCount(bitVector); bit++ ) { 234 CFBitVectorSetBitAtIndex(bitVector, bit, aState); 235 } 236 } 237 238 // returns the number of bits in the bit vector. 239 - (NSInteger) numBits 240 { 241 // return CFBitVectorGetCount(bitVector); 242 return CFBitVectorGetCountOfBit(bitVector, CFRangeMake(0, CFBitVectorGetCount(bitVector)), 1); 243 } 244 245 // returns the number of bits in the bit vector. 246 - (NSUInteger) size 247 { 248 return CFBitVectorGetCount(bitVector); 249 } 250 251 - (void) setSize:(NSUInteger) nBits 252 { 253 CFBitVectorSetCount( bitVector, nBits ); 254 } 255 256 #pragma mark Informational 257 // return a bitmask representation of this bitvector for easy operations 258 - (unsigned long long) bitMask:(NSUInteger) bitNumber 259 { 260 return 1LL << bitNumber; 261 } 262 263 // test a bit (no pun intended) 264 - (BOOL) member:(NSUInteger) bitNumber 265 { 266 return CFBitVectorGetBitAtIndex(bitVector,bitNumber) ? YES : NO; 267 } 268 269 // are all bits off? 270 - (BOOL) isNil 271 { 272 return ((CFBitVectorGetCountOfBit(bitVector, CFRangeMake(0,CFBitVectorGetCount(bitVector)), 1) == 0) ? YES : NO); 273 } 274 275 // return a string representation of the bit vector, indicating by their bitnumber which bits are set 276 - (NSString *) toString 277 { 278 CFIndex length = CFBitVectorGetCount(bitVector); 279 CFIndex currBit; 280 NSMutableString *descString = [NSMutableString stringWithString:@"{"]; 281 BOOL haveInsertedBit = NO; 282 for (currBit = 0; currBit < length; currBit++) { 283 if ( CFBitVectorGetBitAtIndex(bitVector, currBit) ) { 284 if (haveInsertedBit) { 285 [descString appendString:@","]; 286 } 287 [descString appendFormat:@"%d", currBit]; 288 haveInsertedBit = YES; 289 } 290 } 291 [descString appendString:@"}"]; 292 return descString; 293 } 294 295 // debugging aid. GDB invokes this automagically 296 - (NSString *) description 297 { 298 return [self toString]; 299 } 300 301 // NSCopying 302 #pragma mark NSCopying support 303 304 - (id) mutableCopyWithZone:(NSZone *) theZone 305 { 306 ANTLRBitSet *newBitSet = [[ANTLRBitSet allocWithZone:theZone] initWithBitVector:CFBitVectorCreateMutableCopy(kCFAllocatorDefault,0,bitVector)]; 307 return newBitSet; 308 } 309 310 - (CFMutableBitVectorRef) _bitVector 311 { 312 return bitVector; 313 } 314 315 @synthesize bitVector; 316 @end 317 318 NSInteger max(NSInteger a, NSInteger b) 319 { 320 return (a>b)?a:b; 321 } 322 323