Skip to content

HTTPS clone URL

Subversion checkout URL

You can clone with
or
.
Download ZIP
Browse files

Some more helper routines and tests for the state machine and underly…

…ing bitfield.
  • Loading branch information...
commit 6c04370c746ff31b6fda0593e27fe666611df059 1 parent 0f07514
Jim Dovey authored
View
12 AQAppStateMachine/AQAppStateMachine.h
@@ -46,6 +46,11 @@
*/
+ (AQAppStateMachine *) appStateMachine;
+// core value change API
+- (void) setBit: (AQBit) aBit atIndex: (NSUInteger) index ofStateBitsInRange: (NSRange) range;
+- (void) setScalar32Value: (UInt32) value forStateBitsInRange: (NSRange) range;
+- (void) setScalar64Value: (UInt64) value forStateBitsInRange: (NSRange) range;
+
// core notification API— everything else funnels through these functions
- (void) notifyForChangesToStateBitAtIndex: (NSUInteger) index
usingBlock: (void (^)(void)) block;
@@ -87,7 +92,7 @@
@end
-/*!
+/**
This category defines an interface whereby API clients can interact with the state machine using
atomic-sized enumerated value ranges keyed with specific names, rather than knowing the internals
of the (potentially quite large) bitfield layout.
@@ -103,6 +108,11 @@
// generic named bit-range creator -- the others all funnel through here
- (void) addStateMachineValuesUsingBitfieldOfLength: (NSUInteger) length withName: (NSString *) name;
+// setting values -- simple version
+- (void) setValue: (UInt64) value forEnumerationWithName: (NSString *) name;
+- (void) setBitAtIndex: (NSUInteger) index ofEnumerationWithName: (NSString *) name;
+- (void) clearBitAtIndex: (NSUInteger) index ofEnumerationWithName: (NSString *) name;
+
// add notifications for named enumerations
- (void) notifyChangesToStateMachineValuesWithName: (NSString *) name
usingBlock: (void (^)(void)) block;
View
42 AQAppStateMachine/AQAppStateMachine.m
@@ -135,6 +135,21 @@ - (void) notifyForChangesToStateBitsInRange: (NSRange) range usingBlock: (void (
#endif
}
+- (void) setBit: (AQBit) aBit atIndex: (NSUInteger) index ofStateBitsInRange: (NSRange) range
+{
+ [_stateBits setBit: aBit atIndex: range.location + index];
+}
+
+- (void) setScalar32Value: (UInt32) value forStateBitsInRange: (NSRange) range
+{
+ [_stateBits setBitsInRange: range from32BitValue: value];
+}
+
+- (void) setScalar64Value: (UInt64) value forStateBitsInRange: (NSRange) range
+{
+ [_stateBits setBitsInRange: range from64BitValue: value];
+}
+
- (void) notifyForChangesToStateBitsInRange: (NSRange) range
maskedWithInteger: (NSUInteger) mask
usingBlock: (void (^)(void)) block
@@ -283,6 +298,33 @@ - (void) addStateMachineValuesUsingBitfieldOfLength: (NSUInteger) length withNam
});
}
+- (void) setValue: (UInt64) value forEnumerationWithName: (NSString *) name
+{
+ NSRange rng = [self underlyingBitfieldRangeForName: name];
+ if ( rng.location == NSNotFound )
+ return;
+
+ [self setScalar64Value: value forStateBitsInRange: rng];
+}
+
+- (void) setBitAtIndex: (NSUInteger) index ofEnumerationWithName: (NSString *) name
+{
+ NSRange rng = [self underlyingBitfieldRangeForName: name];
+ if ( rng.location == NSNotFound )
+ return;
+
+ [self setBit: 1 atIndex: index ofStateBitsInRange: rng];
+}
+
+- (void) clearBitAtIndex: (NSUInteger) index ofEnumerationWithName: (NSString *) name
+{
+ NSRange rng = [self underlyingBitfieldRangeForName: name];
+ if ( rng.location == NSNotFound )
+ return;
+
+ [self setBit: 0 atIndex: index ofStateBitsInRange: rng];
+}
+
- (void) notifyChangesToStateMachineValuesWithName: (NSString *) name
usingBlock: (void (^)(void)) block
{
View
18 AQAppStateMachine/AQBitfield.h
@@ -198,12 +198,28 @@ typedef CFBit AQBit;
- (void) setBitsFrom32BitValue: (UInt32) value;
/**
- Set the bits in the least-significant four words to those in a 64-bit quantity.
+ Set the bits in the least-significant eight words to those in a 64-bit quantity.
@param value The value whose bits to copy.
*/
- (void) setBitsFrom64BitValue: (UInt64) value;
/**
+ Set the bits in the given range to those in a 32-bit quantity.
+ @param value The value whose bits to copy.
+ @param range The range of bits to modify.
+ @exception NSInvalidArgumentException Thrown if the supplied range is greater than 32 bits in length.
+ */
+- (void) setBitsInRange: (NSRange) range from32BitValue: (UInt32) value;
+
+/**
+ Set the bits in the given range to those in a 64-bit quantity.
+ @param value The value whose bits to copy.
+ @param range The range of bits to modify.
+ @exception NSInvalidArgumentException Thrown if the supplied range is greater than 64 bits in length.
+ */
+- (void) setBitsInRange: (NSRange) range from64BitValue: (UInt64) value;
+
+/**
Copy all 1 bits from another bitfield.
@param bitfield The bitfield with which to merge the receiver.
*/
View
28 AQAppStateMachine/AQBitfield.m
@@ -338,6 +338,34 @@ - (void) setBitsFrom64BitValue: (UInt64) value
}
}
+- (void) setBitsInRange: (NSRange) range from32BitValue: (UInt32) value
+{
+ if ( range.length > 32 )
+ [NSException raise: NSInvalidArgumentException format: @"Range supplied to -%@ must have a length of 32 or less (received range %@)", NSStringFromClass([self class]), NSStringFromRange(range)];
+
+ for ( NSUInteger i = 0; i < range.length; i++, value >>= 1 )
+ {
+ if ( (value & 1) == 1 )
+ [_storage addIndex: range.location + i];
+ else
+ [_storage removeIndex: range.location + i];
+ }
+}
+
+- (void) setBitsInRange: (NSRange) range from64BitValue: (UInt64) value
+{
+ if ( range.length > 64 )
+ [NSException raise: NSInvalidArgumentException format: @"Range supplied to -%@ must have a length of 64 or less (received range %@)", NSStringFromClass([self class]), NSStringFromRange(range)];
+
+ for ( NSUInteger i = 0; i < range.length; i++, value >>= 1 )
+ {
+ if ( (value & 1) == 1 )
+ [_storage addIndex: range.location + i];
+ else
+ [_storage removeIndex: range.location + i];
+ }
+}
+
- (void) unionWithBitfield: (AQBitfield *) bitfield
{
[_storage addIndexes: bitfield->_storage];
View
6 AQAppStateMachine/SortedDictionary/Public/SortedDictionary.m
@@ -17,10 +17,10 @@ @implementation SortedDictionary
// terminated argument list
- (id) initWithObject: (id) firstObject andArglist: (va_list) arglist {
if (self = [self init]) {
- id key, value;
+ id __unsafe_unretained key, value;
if ((value = firstObject)) {
- if ((key = va_arg(arglist, id)) != nil) {
+ if ((key = va_arg(arglist, __unsafe_unretained id)) != nil) {
do {
if (!key || !value) {
@throw [NSException exceptionWithName: NSInvalidArgumentException
@@ -28,7 +28,7 @@ - (id) initWithObject: (id) firstObject andArglist: (va_list) arglist {
}
[tree setObject: value forKey: key];
- } while ((value = va_arg(arglist, id)) && (key = va_arg(arglist, id)));
+ } while ((value = va_arg(arglist, __unsafe_unretained id)) && (key = va_arg(arglist, __unsafe_unretained id)));
}
}
}
View
22 AQAppStateMachineTests/AQAppStateMachineCoreTests.m
@@ -54,16 +54,28 @@
};
@implementation AQAppStateMachineCoreTests
+{
+ AQAppStateMachine * stateMachine;
+}
-- (void) testNamedRanges
+- (void) setUp
{
// temporary version just for the tests
- AQAppStateMachine * stateMachine = [AQAppStateMachine new];
+ stateMachine = [AQAppStateMachine new];
// add the named ranges
[stateMachine addStateMachineValuesFromZeroTo: kSampleOneCount withName: @"Sample One"];
[stateMachine addStateMachineValuesFromZeroTo: kSampleTwoCount withName: @"Sample Two"];
-
+}
+
+- (void) tearDown
+{
+ // ARC code-- no -release, just nilify it
+ stateMachine = nil;
+}
+
+- (void) testNamedRanges
+{
// the state machine will round up to byte-size to allocate ranges, like so:
NSUInteger sampleOneBitCount = (kSampleOneCount + 7) & ~7;
NSUInteger sampleTwoBitCount = (kSampleTwoCount + 7) & ~7;
@@ -72,4 +84,8 @@ - (void) testNamedRanges
STAssertTrue(NSEqualRanges(NSMakeRange(sampleOneBitCount, sampleTwoBitCount), [stateMachine underlyingBitfieldRangeForName: @"Sample Two"]), @"The underlying range is unexpectedly %@", NSStringFromRange([stateMachine underlyingBitfieldRangeForName: @"Sample Two"]));
}
+- (void) testChangesToSingleBit
+{
+}
+
@end
View
2  AQAppStateMachineTests/AQAppStateMachineTests-Info.plist
@@ -7,7 +7,7 @@
<key>CFBundleExecutable</key>
<string>${EXECUTABLE_NAME}</string>
<key>CFBundleIdentifier</key>
- <string>___VARIABLE_bundleIdentifierPrefix:bundleIdentifier___.${PRODUCT_NAME:rfc1034identifier}</string>
+ <string>net.alanquatermain.${PRODUCT_NAME:rfc1034identifier}</string>
<key>CFBundleInfoDictionaryVersion</key>
<string>6.0</string>
<key>CFBundlePackageType</key>
View
50 AQAppStateMachineTests/AQBitfieldTests.m
@@ -112,6 +112,56 @@ - (void) testSetBitsFrom64BitScalar
STAssertTrue([bitfield countOfBit: 1 inRange: test6] == 3, @"Expected %@ to have 3 bits set in range %@, but got %lu", bitfield, NSStringFromRange(test3), (unsigned long)[bitfield countOfBit: 1 inRange: test6]);
}
+- (void) setSetBitsInRangeFrom32BitScalar
+{
+ AQBitfield * bitfield = [AQBitfield new];
+
+ NSRange setRange = NSMakeRange(10, 32);
+ [bitfield setBitsInRange: setRange from32BitValue: 0xFF00FFFF];
+
+ NSRange test1 = NSMakeRange(setRange.location, 16); // should be 16 bits set
+ NSRange test2 = NSMakeRange(setRange.location + 16, 8); // should be 0 bits set
+ NSRange test3 = NSMakeRange(setRange.location + 24, 8); // should be 8 bits set
+
+ STAssertTrue([bitfield countOfBit: 1 inRange: test1] == 16, @"Expected %@ to have 16 bits set in range %@, but got %lu", bitfield, NSStringFromRange(test1), (unsigned long)[bitfield countOfBit: 1 inRange: test1]);
+ STAssertTrue([bitfield countOfBit: 1 inRange: test2] == 0, @"Expected %@ to have 0 bits set in range %@, but got %lu", bitfield, NSStringFromRange(test2), (unsigned long)[bitfield countOfBit: 1 inRange: test2]);
+ STAssertTrue([bitfield countOfBit: 1 inRange: test3] == 8, @"Expected %@ to have 8 bits set in range %@, but got %lu", bitfield, NSStringFromRange(test3), (unsigned long)[bitfield countOfBit: 1 inRange: test3]);
+
+ NSRange before = NSMakeRange(0, setRange.location);
+ NSRange after = NSMakeRange(NSMaxRange(setRange), 20);
+
+ STAssertTrue([bitfield countOfBit: 1 inRange: before] == 0, @"Expected %@ to have no bits set in range %@, but got %lu", bitfield, NSStringFromRange(before), (unsigned long)[bitfield countOfBit: 1 inRange: before]);
+ STAssertTrue([bitfield countOfBit: 1 inRange: after] == 0, @"Expected %@ to have no bits set in range %@, but got %lu", bitfield, NSStringFromRange(before), (unsigned long)[bitfield countOfBit: 1 inRange: after]);
+}
+
+- (void) testSetBitsInRangeFrom64BitScalar
+{
+ AQBitfield * bitfield = [AQBitfield new];
+
+ NSRange setRange = NSMakeRange(10, 64);
+ [bitfield setBitsInRange: setRange from64BitValue: 0xE000007FFF00FFFFull];
+
+ NSRange test1 = NSMakeRange(setRange.location, 16); // should be 16 bits set
+ NSRange test2 = NSMakeRange(setRange.location + 16, 8); // should be 0 bits set
+ NSRange test3 = NSMakeRange(setRange.location + 24, 8); // should be 8 bits set
+ NSRange test4 = NSMakeRange(setRange.location + 32, 8); // should be 7 bits set
+ NSRange test5 = NSMakeRange(setRange.location + 40, 16); // should be 0 bits set
+ NSRange test6 = NSMakeRange(setRange.location + 56, 8); // should be 3 bits set
+
+ STAssertTrue([bitfield countOfBit: 1 inRange: test1] == 16, @"Expected %@ to have 16 bits set in range %@, but got %lu", bitfield, NSStringFromRange(test1), (unsigned long)[bitfield countOfBit: 1 inRange: test1]);
+ STAssertTrue([bitfield countOfBit: 1 inRange: test2] == 0, @"Expected %@ to have 0 bits set in range %@, but got %lu", bitfield, NSStringFromRange(test2), (unsigned long)[bitfield countOfBit: 1 inRange: test2]);
+ STAssertTrue([bitfield countOfBit: 1 inRange: test3] == 8, @"Expected %@ to have 8 bits set in range %@, but got %lu", bitfield, NSStringFromRange(test3), (unsigned long)[bitfield countOfBit: 1 inRange: test3]);
+ STAssertTrue([bitfield countOfBit: 1 inRange: test4] == 7, @"Expected %@ to have 7 bits set in range %@, but got %lu", bitfield, NSStringFromRange(test3), (unsigned long)[bitfield countOfBit: 1 inRange: test4]);
+ STAssertTrue([bitfield countOfBit: 1 inRange: test5] == 0, @"Expected %@ to have 0 bits set in range %@, but got %lu", bitfield, NSStringFromRange(test3), (unsigned long)[bitfield countOfBit: 1 inRange: test5]);
+ STAssertTrue([bitfield countOfBit: 1 inRange: test6] == 3, @"Expected %@ to have 3 bits set in range %@, but got %lu", bitfield, NSStringFromRange(test3), (unsigned long)[bitfield countOfBit: 1 inRange: test6]);
+
+ NSRange before = NSMakeRange(0, setRange.location);
+ NSRange after = NSMakeRange(NSMaxRange(setRange), 20);
+
+ STAssertTrue([bitfield countOfBit: 1 inRange: before] == 0, @"Expected %@ to have no bits set in range %@, but got %lu", bitfield, NSStringFromRange(before), (unsigned long)[bitfield countOfBit: 1 inRange: before]);
+ STAssertTrue([bitfield countOfBit: 1 inRange: after] == 0, @"Expected %@ to have no bits set in range %@, but got %lu", bitfield, NSStringFromRange(before), (unsigned long)[bitfield countOfBit: 1 inRange: after]);
+}
+
- (void) testBitCount
{
AQBitfield * bitfield = [AQBitfield new];
Please sign in to comment.
Something went wrong with that request. Please try again.