ControlByte payloadSize determined for values between 29 and 284. On to the next challenge.

Signed-off-by: Adam Rocska <adam.rocska@adams.solutions>
This commit is contained in:
Adam Rocska 2020-04-30 18:11:56 +02:00
parent 934dadc269
commit cbe43c1bc6
2 changed files with 57 additions and 7 deletions

View File

@ -10,18 +10,27 @@ struct ControlByte {
let firstByte = bytes.first! let firstByte = bytes.first!
let typeDefinitionOnFirstByte = firstByte &>> 5 let typeDefinitionOnFirstByte = firstByte &>> 5
let isExtendedType = typeDefinitionOnFirstByte == 0b0000_0000
guard let type = typeDefinitionOnFirstByte != 0b0000_0000 guard let type = isExtendedType
? DataType(rawValue: typeDefinitionOnFirstByte) ? DataType(rawValue: bytes[bytes.index(after: bytes.startIndex)] + 7)
: DataType(rawValue: bytes[bytes.index(after: bytes.startIndex)] + 7) : DataType(rawValue: typeDefinitionOnFirstByte)
else { else {
return nil return nil
} }
let sliceFrom = isExtendedType
? bytes.index(bytes.startIndex, offsetBy: 2, limitedBy: bytes.endIndex) ?? bytes.startIndex
: bytes.index(bytes.startIndex, offsetBy: 1, limitedBy: bytes.endIndex) ?? bytes.startIndex
let bytesAfterTypeSpecifyingBytes = bytes[sliceFrom...]
let payloadSizeDefinition = firstByte & 0b0001_1111 let payloadSizeDefinition = firstByte & 0b0001_1111
switch payloadSizeDefinition { switch payloadSizeDefinition {
case _ where payloadSizeDefinition < 29: case _ where payloadSizeDefinition < 29:
payloadSize = UInt32(payloadSizeDefinition) payloadSize = UInt32(payloadSizeDefinition)
case 29:
payloadSize = 29 + UInt32(bytesAfterTypeSpecifyingBytes.first ?? 0)
default: default:
return nil return nil
} }

View File

@ -55,21 +55,62 @@ class ControlByteTest: XCTestCase {
XCTAssertNil(ControlByte(bytes: Data([0b0000_1111, 0b0000_1111, 0b0000_0000]))) XCTAssertNil(ControlByte(bytes: Data([0b0000_1111, 0b0000_1111, 0b0000_0000])))
} }
fileprivate typealias PayloadSizeTestDefinition = (expectedPayloadSize: UInt32, bytes: Data)
func testInit_payloadSizeDefinition_lessThan29() { func testInit_payloadSizeDefinition_lessThan29() {
let testInput: [(expectedPayloadSize: UInt32, byte: UInt8)] = ControlByteTest let nonExtendedRawValues: [PayloadSizeTestDefinition] = ControlByteTest
.nonExtendedRawValues .nonExtendedRawValues
.reduce([]) { byteSequence, typeDefinition in .reduce([]) { byteSequence, typeDefinition in
byteSequence + (0..<29).map({ byteSequence + (0..<29).map({
(expectedPayloadSize: UInt32($0), byte: $0 | (typeDefinition << 5)) (expectedPayloadSize: UInt32($0), bytes: Data([$0 | (typeDefinition << 5)]))
})
}
let extendedRawValues: [PayloadSizeTestDefinition] = ControlByteTest
.extendedRawValues
.reduce([]) { byteSequence, typeDefinition in
byteSequence + (0..<29).map({
(expectedPayloadSize: UInt32($0), bytes: Data([$0, typeDefinition - 7]))
}) })
} }
for (expectedPayloadSize, byte) in testInput { for (expectedPayloadSize, bytes) in (nonExtendedRawValues + extendedRawValues) {
XCTAssertEqual( XCTAssertEqual(
expectedPayloadSize, expectedPayloadSize,
ControlByte(bytes: Data([byte]))?.payloadSize ControlByte(bytes: bytes)?.payloadSize
) )
} }
} }
func testInit_payloadSizeDefinition_exactly29() {
let nonExtendedRawValues: [PayloadSizeTestDefinition] = ControlByteTest
.nonExtendedRawValues
.reduce([]) { byteSequence, typeDefinition in
byteSequence + (29..<285).map({
(
expectedPayloadSize: UInt32($0),
bytes: Data([UInt8(29) | (typeDefinition << 5), UInt8($0 - 29)])
)
})
}
let extendedRawValues: [PayloadSizeTestDefinition] = ControlByteTest
.extendedRawValues
.reduce([]) { byteSequence, typeDefinition in
byteSequence + (29..<285).map({
(
expectedPayloadSize: UInt32($0),
bytes: Data([UInt8(29), typeDefinition - 7, UInt8($0 - 29)])
)
})
}
for (expectedPayloadSize, bytes) in (nonExtendedRawValues + extendedRawValues) {
XCTAssertEqual(
expectedPayloadSize,
ControlByte(bytes: bytes)?.payloadSize,
"Expected a payload size of \(expectedPayloadSize), but instead got \(ControlByte(bytes: bytes)?.payloadSize)"
)
}
}
} }