| //␊ | 
| //  BitArray.m␊ | 
| //  oneIP␊ | 
| //␊ | 
| //  Created by Bret Deasy on 7/16/13.␊ | 
| //  Copyright (c) 2013 Bret Deasy. All rights reserved.␊ | 
| //␊ | 
| ␊ | 
| #import "BitArray.h"␊ | 
| ␊ | 
| @implementation BitArray␊ | 
| ␊ | 
| @synthesize bitVector;␊ | 
| ␊ | 
| /**␊ | 
| Initialize with empty bitVector␊ | 
| **/␊ | 
| - (id)init␊ | 
| {␊ | 
| self = [super init];␊ | 
| ␊ | 
| if (self)␊ | 
| {␊ | 
| bitVector = CFBitVectorCreateMutable(kCFAllocatorDefault, 0);␊ | 
| }␊ | 
| ␊ | 
| return self;␊ | 
| }␊ | 
| ␊ | 
| /**␊ | 
| Returns a BitArray object initialized by copying the bits from another given BitArray.␊ | 
| **/␊ | 
| - (id)initWithBitArray:(BitArray *)bitArray␊ | 
| {␊ | 
| return [self initWithBitVector:[bitArray bitVector]];␊ | 
| }␊ | 
| ␊ | 
| /**␊ | 
| Initialize with capacity-sized bitVector containing all zeroes.␊ | 
| **/␊ | 
| - (id)initWithCount:(CFIndex)count␊ | 
| {␊ | 
| self = [super init];␊ | 
| ␊ | 
| if (self)␊ | 
| {␊ | 
| bitVector = CFBitVectorCreateMutable(kCFAllocatorDefault, 0);␊ | 
| [self setCount:count];␊ | 
| }␊ | 
| ␊ | 
| return self;␊ | 
| }␊ | 
| ␊ | 
| /**␊ | 
| Initializer from a given string of 0s and/or 1s.␊ | 
| */␊ | 
| - (id)initWithString:(NSString *)bitString␊ | 
| {␊ | 
| self = [super init];␊ | 
| ␊ | 
| if (self)␊ | 
| {␊ | 
| int length = [bitString length];␊ | 
| CFMutableBitVectorRef _bitVector = CFBitVectorCreateMutable(kCFAllocatorDefault, length);␊ | 
| CFBitVectorSetCount(_bitVector, length);␊ | 
| ␊ | 
| for (int i = 0; i < length; i++)␊ | 
| {␊ | 
| int bitAtIndex = [bitString characterAtIndex:i] - 48;␊ | 
| CFBitVectorSetBitAtIndex(_bitVector, i, bitAtIndex);␊ | 
| }␊ | 
| ␊ | 
| bitVector = CFBitVectorCreateMutableCopy(kCFAllocatorDefault, length, _bitVector);␊ | 
| ␊ | 
| CFRelease(_bitVector);␊ | 
| }␊ | 
| ␊ | 
| return self;␊ | 
| }␊ | 
| ␊ | 
| /**␊ | 
| Initializer from a given CFBitVectorRef.␊ | 
| */␊ | 
| - (id)initWithBitVector:(CFMutableBitVectorRef)_bitVector␊ | 
| {␊ | 
| self = [super init];␊ | 
| ␊ | 
| if (self)␊ | 
| {␊ | 
| bitVector = CFBitVectorCreateMutableCopy(kCFAllocatorDefault, CFBitVectorGetCount(_bitVector), _bitVector);␊ | 
| }␊ | 
| ␊ | 
| return self;␊ | 
| }␊ | 
| ␊ | 
| /**␊ | 
| Initialize from a given Int. Integer must be 0 or greater.␊ | 
| **/␊ | 
| - (id)initWithInteger:(int)value␊ | 
| {␊ | 
| self = [super init];␊ | 
| ␊ | 
| if (self)␊ | 
| {␊ | 
| int capacity;␊ | 
| ␊ | 
| if (value <= 0)␊ | 
| {␊ | 
| bitVector = CFBitVectorCreateMutable(kCFAllocatorDefault, 1);␊ | 
| CFBitVectorSetCount(bitVector, 1);␊ | 
| } else {␊ | 
| capacity = floor(log2(value))+1;␊ | 
| bitVector = CFBitVectorCreateMutable(kCFAllocatorDefault, capacity);␊ | 
| CFBitVectorSetCount(bitVector, capacity);␊ | 
| ␊ | 
| for (int i = capacity - 1; i >= 0; i--)␊ | 
| {␊ | 
| CFBitVectorSetBitAtIndex(bitVector, i, (value & 1));␊ | 
| value>>=1;␊ | 
| }␊ | 
| }␊ | 
| }␊ | 
| ␊ | 
| return self;␊ | 
| }␊ | 
| ␊ | 
| /**␊ | 
| Returns the AND of the receiver's bitVector and the passed BitArray's bitVector.␊ | 
| */␊ | 
| - (BitArray *)bitArrayByANDingWithBitArray:(BitArray *)andBitArray␊ | 
| {␊ | 
| CFBit aBit;␊ | 
| CFBit bBit;␊ | 
| CFBit resultBit;␊ | 
| ␊ | 
| [self equalizeBitVector:andBitArray];␊ | 
| int capacity = [self count];␊ | 
| CFMutableBitVectorRef resultBitArray = CFBitVectorCreateMutable(kCFAllocatorDefault, capacity);␊ | 
| CFBitVectorSetCount(resultBitArray, capacity);␊ | 
| ␊ | 
| for (int i = 0; i < capacity; i++)␊ | 
| {␊ | 
| aBit = CFBitVectorGetBitAtIndex(bitVector, i);␊ | 
| bBit = CFBitVectorGetBitAtIndex([andBitArray bitVector], i);␊ | 
| ␊ | 
| resultBit = aBit & bBit;␊ | 
| CFBitVectorSetBitAtIndex(resultBitArray, i, resultBit);␊ | 
| }␊ | 
| ␊ | 
| BitArray *retBitArray = [[BitArray alloc] initWithBitVector:resultBitArray];␊ | 
| CFRelease(resultBitArray);␊ | 
| ␊ | 
| return retBitArray;␊ | 
| ␊ | 
| }␊ | 
| ␊ | 
| /**␊ | 
| Returns the OR of the receiver's bitVector with the passed BitArray's bitVector.␊ | 
| **/␊ | 
| - (BitArray *)bitArrayByORingWithBitArray:(BitArray *)orBitArray␊ | 
| {␊ | 
| CFBit aBit;␊ | 
| CFBit bBit;␊ | 
| CFBit resultBit;␊ | 
| ␊ | 
| [self equalizeBitVector:orBitArray];␊ | 
| int capacity = [self count];␊ | 
| ␊ | 
| CFMutableBitVectorRef resultBitArray = CFBitVectorCreateMutable(kCFAllocatorDefault, capacity);␊ | 
| CFBitVectorSetCount(resultBitArray, capacity);␊ | 
| ␊ | 
| for (int i = 0; i < capacity; i++)␊ | 
| {␊ | 
| aBit = CFBitVectorGetBitAtIndex(bitVector, i);␊ | 
| bBit = CFBitVectorGetBitAtIndex([orBitArray bitVector], i);␊ | 
| ␊ | 
| resultBit = aBit | bBit;␊ | 
| CFBitVectorSetBitAtIndex(resultBitArray, i, resultBit);␊ | 
| }␊ | 
| ␊ | 
| BitArray *retBitArray = [[BitArray alloc] initWithBitVector:resultBitArray];␊ | 
| CFRelease(resultBitArray);␊ | 
| ␊ | 
| return retBitArray;␊ | 
| }␊ | 
| ␊ | 
| /**␊ | 
| Returns the NOT of the receiver's bitVector.␊ | 
| **/␊ | 
| - (BitArray *)bitArrayByNOTingBitArray␊ | 
| {␊ | 
| CFBit bit;␊ | 
| CFBit resultBit;␊ | 
| ␊ | 
| int capacity = [self count];␊ | 
| ␊ | 
| CFMutableBitVectorRef resultBitArray = CFBitVectorCreateMutable(kCFAllocatorDefault, capacity);␊ | 
| CFBitVectorSetCount(resultBitArray, capacity);␊ | 
| ␊ | 
| for (int i = 0; i < capacity; i++)␊ | 
| {␊ | 
| bit = CFBitVectorGetBitAtIndex(bitVector, i);␊ | 
| resultBit = !bit;␊ | 
| ␊ | 
| CFBitVectorSetBitAtIndex(resultBitArray, i, resultBit);␊ | 
| }␊ | 
| ␊ | 
| BitArray *retBitArray = [[BitArray alloc] initWithBitVector:resultBitArray];␊ | 
| CFRelease(resultBitArray);␊ | 
| ␊ | 
| return retBitArray;␊ | 
| }␊ | 
| ␊ | 
| /**␊ | 
| Returns the number of bits in the receiver's bitVector.␊ | 
| **/␊ | 
| - (int)count␊ | 
| {␊ | 
| return CFBitVectorGetCount(bitVector);␊ | 
| }␊ | 
| ␊ | 
| /**␊ | 
| Sets the size of the receiver's bitVector␊ | 
| **/␊ | 
| - (void)setCount:(CFIndex)count␊ | 
| {␊ | 
| CFBitVectorSetCount(bitVector, count);␊ | 
| }␊ | 
| /**␊ | 
| Makes the receiver's bitVector and the parameter's of equal size␊ | 
| **/␊ | 
| - (void)equalizeBitVector:(BitArray *)bitArray␊ | 
| {␊ | 
| int bitVectorCapacity = [self count];␊ | 
| int compareBitVectorCapacity = [bitArray count];␊ | 
| ␊ | 
| if (bitVectorCapacity < compareBitVectorCapacity)␊ | 
| {␊ | 
| [self padToCapacity:compareBitVectorCapacity];␊ | 
| } else if (bitVectorCapacity > compareBitVectorCapacity) {␊ | 
| [bitArray padToCapacity:bitVectorCapacity];␊ | 
| }␊ | 
| }␊ | 
| ␊ | 
| /**␊ | 
| Pads 0s to the left to make the bitVector's capacity match the parameter.␊ | 
| */␊ | 
| - (void)padToCapacity:(int)capacity␊ | 
| {␊ | 
| int difference = capacity - [self count];␊ | 
| ␊ | 
| if (difference <= 0)␊ | 
| {␊ | 
| return;␊ | 
| }␊ | 
| ␊ | 
| ␊ | 
| CFMutableBitVectorRef tempVector = CFBitVectorCreateMutable(kCFAllocatorDefault, difference);␊ | 
| CFBitVectorSetCount(tempVector, difference);␊ | 
| ␊ | 
| BitArray *insertBitArray = [[BitArray alloc] initWithBitVector:tempVector];␊ | 
| ␊ | 
| [self insertBitArray:insertBitArray atIndex:0];␊ | 
| //    for (int i = difference; i < capacity; difference++)␊ | 
| //    {␊ | 
| //        CFBitVectorSetBitAtIndex(tempVector, i, CFBitVectorGetBitAtIndex(bitVector, currIndex));␊ | 
| //        currIndex++;␊ | 
| //    }␊ | 
| //    ␊ | 
| //    bitVector = CFBitVectorCreateMutableCopy(kCFAllocatorDefault, capacity, tempVector);␊ | 
| //    CFRelease(tempVector);␊ | 
| }␊ | 
| ␊ | 
| /**␊ | 
| Returns a new BitArray made by appending a given BitArray to the receiver.␊ | 
| **/␊ | 
| - (BitArray *)bitArrayByAppendingBitArray:(BitArray *)bitArray␊ | 
| {␊ | 
| //     return [[[BitArray alloc] initWithBitArray:self] bitArrayByAppendingBitArray:bitArray];␊ | 
| BitArray *retBitArray = [[BitArray alloc] initWithBitArray:self];␊ | 
| [retBitArray insertBitArray:bitArray atIndex:[self count]];␊ | 
| ␊ | 
| return retBitArray;␊ | 
| }␊ | 
| ␊ | 
| /**␊ | 
| Returns BitArray containing the bitVector of the value parameter added to the receiver's bitVector.␊ | 
| **/␊ | 
| - (BitArray *)bitArrayByAddingInteger:(int)value␊ | 
| {␊ | 
| return [self performMathOperation:Add withInt:value];␊ | 
| }␊ | 
| ␊ | 
| /**␊ | 
| Returns BitArray containing the bitVector of the value parameter subtracted from the receiver's bitVector.␊ | 
| **/␊ | 
| - (BitArray *)bitArrayBySubtractingInteger:(int)value␊ | 
| {␊ | 
| return [self performMathOperation:Subtract withInt:value];␊ | 
| }␊ | 
| ␊ | 
| /**␊ | 
| Returns BitArray represented after performing the selected math operation with the given value on the receiver.␊ | 
| **/␊ | 
| - (BitArray *)performMathOperation:(Operation)op withInt:(int)value␊ | 
| {␊ | 
| int capacity = [self count];␊ | 
| ␊ | 
| CFMutableBitVectorRef bits = CFBitVectorCreateMutable(kCFAllocatorDefault, capacity);␊ | 
| CFBitVectorSetCount(bits, capacity);␊ | 
| ␊ | 
| CFMutableBitVectorRef result = CFBitVectorCreateMutable(kCFAllocatorDefault, 2);␊ | 
| CFBitVectorSetCount(result, 2);␊ | 
| ␊ | 
| BitArray *valueBitArray = [[BitArray alloc] initWithInteger:value];␊ | 
| [self equalizeBitVector:valueBitArray];␊ | 
| ␊ | 
| for (int i = capacity - 1; i >= 0; i--)␊ | 
| {␊ | 
| int aBit = CFBitVectorGetBitAtIndex(bitVector, i);␊ | 
| int bBit = CFBitVectorGetBitAtIndex([valueBitArray bitVector], i);␊ | 
| int cBit = CFBitVectorGetBitAtIndex(result, 1);␊ | 
| ␊ | 
| if (op == Add)␊ | 
| {␊ | 
| result = [self fullAdderWithaBit:aBit␊ | 
| bBit:bBit␊ | 
| cBit:cBit];␊ | 
| } else if (op == Subtract) {␊ | 
| result = [self fullSubtractorWithaBit:aBit␊ | 
| bBit:bBit␊ | 
| cBit:cBit];␊ | 
| }␊ | 
| ␊ | 
| CFBitVectorSetBitAtIndex(bits, i, CFBitVectorGetBitAtIndex(result, 0));␊ | 
| }␊ | 
| ␊ | 
| BitArray *retBitArray = [[BitArray alloc] initWithBitVector:bits];␊ | 
| CFRelease(result);␊ | 
| CFRelease(bits);␊ | 
| ␊ | 
| return retBitArray;␊ | 
| }␊ | 
| ␊ | 
| /**␊ | 
| Returns the sum bit and carry bit after performing an addition operation.␊ | 
| **/␊ | 
| - (CFMutableBitVectorRef)fullAdderWithaBit:(BOOL)aBit bBit:(BOOL)bBit cBit:(BOOL)cBit␊ | 
| {␊ | 
| //bit0 = sum bit␊ | 
| //bit1 = carry bit␊ | 
| BOOL bit0 = (aBit ^ bBit) ^ cBit;␊ | 
| BOOL bit1 = (aBit & bBit) | (bBit & cBit) | (aBit & cBit);␊ | 
| ␊ | 
| CFMutableBitVectorRef retBitVector = CFBitVectorCreateMutable(kCFAllocatorDefault, 2);␊ | 
| CFBitVectorSetCount(retBitVector, 2);␊ | 
| CFBitVectorSetBitAtIndex(retBitVector, 0, bit0);␊ | 
| CFBitVectorSetBitAtIndex(retBitVector, 1, bit1);␊ | 
| ␊ | 
| return retBitVector;␊ | 
| }␊ | 
| ␊ | 
| /**␊ | 
| Returns the sum bit and carry bit after performing an subtraction operation.␊ | 
| **/␊ | 
| - (CFMutableBitVectorRef)fullSubtractorWithaBit:(BOOL)aBit bBit:(BOOL)bBit cBit:(BOOL)cBit␊ | 
| {␊ | 
| //bit0 = sum bit␊ | 
| //bit1 = carry bit␊ | 
| BOOL bit0 = aBit ^ bBit ^ cBit;␊ | 
| BOOL bit1 = (cBit & (aBit ^ bBit)) | (!aBit & bBit);␊ | 
| ␊ | 
| CFMutableBitVectorRef retBitVector = CFBitVectorCreateMutable(kCFAllocatorDefault, 2);␊ | 
| CFBitVectorSetCount(retBitVector, 2);␊ | 
| CFBitVectorSetBitAtIndex(retBitVector, 0, bit0);␊ | 
| CFBitVectorSetBitAtIndex(retBitVector, 1, bit1);␊ | 
| ␊ | 
| return retBitVector;␊ | 
| }␊ | 
| ␊ | 
| /**␊ | 
| Returns true if the receiver's bitVector is equal to that of the parameter's.␊ | 
| **/␊ | 
| - (BOOL)equalToBitArray:(BitArray *)bitArray␊ | 
| {␊ | 
| CFBit bit;␊ | 
| CFBit bitCompare;␊ | 
| ␊ | 
| for (int i = 0; i < [self count]; i++)␊ | 
| {␊ | 
| bit = CFBitVectorGetBitAtIndex(bitVector, i);␊ | 
| bitCompare = CFBitVectorGetBitAtIndex([bitArray bitVector], i);␊ | 
| ␊ | 
| if (bit != bitCompare)␊ | 
| {␊ | 
| return NO;␊ | 
| }␊ | 
| }␊ | 
| ␊ | 
| return YES;␊ | 
| }␊ | 
| ␊ | 
| ␊ | 
| /**␊ | 
| Returns true if the receiver's bitVector is greater than or equal to that of the parameter's.␊ | 
| **/␊ | 
| - (BOOL)greaterThanOrEqualToBitArray:(BitArray *)bitArray␊ | 
| {␊ | 
| return ([self greaterThanBitArray:bitArray] || [self equalToBitArray:bitArray]);␊ | 
| }␊ | 
| ␊ | 
| /**␊ | 
| Returns true if the receiver's bitVector is less than or equal to that of the parameter's.␊ | 
| **/␊ | 
| - (BOOL)lessThanOrEqualToBitArray:(BitArray *)bitArray␊ | 
| {␊ | 
| return ([self lessThanBitArray:bitArray] || [self equalToBitArray:bitArray]);␊ | 
| }␊ | 
| ␊ | 
| /**␊ | 
| Returns true if the receiver's bitVector is greater than that of the parameter.␊ | 
| **/␊ | 
| - (BOOL)greaterThanBitArray:(BitArray *)bitArray␊ | 
| {␊ | 
| [self equalizeBitVector:bitArray];␊ | 
| ␊ | 
| CFBit bit;␊ | 
| CFBit compareBit;␊ | 
| ␊ | 
| for (int i = [self count] - 1; i >= 0; i--)␊ | 
| {␊ | 
| bit = [self bitAtIndex:i];␊ | 
| compareBit = [bitArray bitAtIndex:i];␊ | 
| ␊ | 
| if (bit > compareBit)␊ | 
| {␊ | 
| return YES;␊ | 
| } else if (bit < compareBit) {␊ | 
| return NO;␊ | 
| }␊ | 
| }␊ | 
| ␊ | 
| return NO;␊ | 
| }␊ | 
| ␊ | 
| /**␊ | 
| Returns true of the receiver's bitVector is less than that of the parameter's␊ | 
| **/␊ | 
| - (BOOL)lessThanBitArray:(BitArray *)bitArray␊ | 
| {␊ | 
| [self equalizeBitVector:bitArray];␊ | 
| ␊ | 
| CFBit bit;␊ | 
| CFBit compareBit;␊ | 
| ␊ | 
| for (int i = [self count]; i > 0; i--)␊ | 
| {␊ | 
| bit = [self bitAtIndex:i];␊ | 
| compareBit = [bitArray bitAtIndex:i];␊ | 
| ␊ | 
| if (bit < compareBit)␊ | 
| {␊ | 
| return YES;␊ | 
| } else if (bit > compareBit) {␊ | 
| return NO;␊ | 
| }␊ | 
| }␊ | 
| ␊ | 
| return NO;␊ | 
| }␊ | 
| ␊ | 
| /**␊ | 
| Returns the bit from the receiver's bitVector at the given index.␊ | 
| **/␊ | 
| - (CFBit)bitAtIndex:(CFIndex)index␊ | 
| {␊ | 
| return CFBitVectorGetBitAtIndex(bitVector, index);␊ | 
| }␊ | 
| ␊ | 
| /**␊ | 
| Sets the bit of the receiver's bitVector at the given index to the given value.␊ | 
| **/␊ | 
| - (void)setBitAtIndex:(CFIndex)index toValue:(CFBit)bit␊ | 
| {␊ | 
| CFBitVectorSetBitAtIndex(bitVector, index, bit);␊ | 
| }␊ | 
| ␊ | 
| /**␊ | 
| Inserts the given bitArray into the receiver at the given index. Receiver will expand as needed.␊ | 
| **/␊ | 
| - (void)insertBitArray:(BitArray *)bitArray atIndex:(CFIndex)index␊ | 
| {␊ | 
| int count = [self count];␊ | 
| int newCount = count + [bitArray count];␊ | 
| int difference = [bitArray count];␊ | 
| int currIndex = 0;␊ | 
| ␊ | 
| [self setCount:newCount];␊ | 
| ␊ | 
| for (int i = count-1; i >= index; i--)␊ | 
| {␊ | 
| [self setBitAtIndex:i+difference toValue:[self bitAtIndex:i]];␊ | 
| }␊ | 
| ␊ | 
| for (int i = index; i < index+difference; i++)␊ | 
| {␊ | 
| [self setBitAtIndex:i toValue:[bitArray bitAtIndex:currIndex]];␊ | 
| currIndex++;␊ | 
| }␊ | 
| //    if ([bitArray count] + index >= [self count])␊ | 
| //    {␊ | 
| //        [self setCount:[bitArray count] + index + 1];␊ | 
| //    }␊ | 
| //    for (int i = 0; i < [bitArray count]; i++)␊ | 
| //    {␊ | 
| //        CFBitVectorSetBitAtIndex(bitVector, index+i, [bitArray bitAtIndex:i]);␊ | 
| //    }␊ | 
| }␊ | 
| ␊ | 
| /**␊ | 
| Returns the int value of the bits in the given range of the receiver's bitVector.␊ | 
| **/␊ | 
| - (int)bitsInRange:(CFRange)range␊ | 
| {␊ | 
| int quotient = floor(range.length / 8);␊ | 
| Byte *bytes = malloc(sizeof(Byte) * quotient);␊ | 
| unsigned int byteValue = 0;␊ | 
| ␊ | 
| CFBitVectorGetBits(bitVector, range, bytes);␊ | 
| memcpy(&byteValue, bytes, quotient);␊ | 
| //ensure big-endianness␊ | 
| if (quotient > 1)␊ | 
| {␊ | 
| byteValue = htons(byteValue);␊ | 
| }␊ | 
| ␊ | 
| return byteValue;␊ | 
| }␊ | 
| ␊ | 
| /**␊ | 
| Returns the string representation of the receiver.␊ | 
| **/␊ | 
| - (NSString *)stringValue␊ | 
| {␊ | 
| NSString *retString = @"";␊ | 
| ␊ | 
| for (int i = 0; i < [self count]; i++)␊ | 
| {␊ | 
| retString = [retString stringByAppendingFormat:@"%ld", [self bitAtIndex:i]];␊ | 
| }␊ | 
| ␊ | 
| return  retString;␊ | 
| }␊ | 
| ␊ | 
| -(void)dealloc␊ | 
| {␊ | 
| CFRelease(bitVector);␊ | 
| }␊ | 
| ␊ | 
| @end␊ |