Work in progress with the decoder. I want to avoid creating a copy in memory just because maxmind's binary data format sucks jack's shit...

Signed-off-by: Adam Rocska <adam.rocska@adams.solutions>
This commit is contained in:
Adam Rocska 2020-05-03 17:41:57 +02:00
parent 4ab4518902
commit 9adc855359
2 changed files with 105 additions and 7 deletions

View File

@ -38,9 +38,17 @@ class Decoder {
}
}
func decode(_ data: Data) -> UInt16 {
var wellSizedData = unpack(data, toBytesLength: 2)
let value = UnsafeRawPointer(&wellSizedData).load(as: UInt16.self)
func decode<T>(_ data: Data) -> T where T: FixedWidthInteger, T: UnsignedInteger {
var wellSizedData = unpack(data, toBytesLength: MemoryLayout<T>.size)
let value = UnsafeRawPointer(&wellSizedData).load(as: T.self)
return input == .big ? value.bigEndian : value.littleEndian
}
func decode<T>(_ data: Data) -> T where T: FixedWidthInteger, T: SignedInteger {
var wellSizedData = unpack(data, toBytesLength: MemoryLayout<T>.size)
let value = UnsafeRawPointer(&wellSizedData).load(as: T.self)
return input == .big ? value.bigEndian : value.littleEndian
}
}

View File

@ -4,7 +4,7 @@ import XCTest
fileprivate typealias TestSpec<T> = (expected: T, input: Data)
fileprivate let testSpecs: [TestSpec<UInt16>] = [
fileprivate let testSpecs_uInt16: [TestSpec<UInt16>] = [
(expected: 0, input: Data()),
(expected: 0, input: Data(count: 1)),
(expected: 0, input: Data(count: 2)),
@ -17,16 +17,106 @@ fileprivate let testSpecs: [TestSpec<UInt16>] = [
(expected: 14200, input: Data(count: 14) + Data([0b0011_0111, 0b0111_1000]))
]
fileprivate let testSpecs_uInt32: [TestSpec<UInt32>] = [
(expected: 0, input: Data()),
(expected: 0, input: Data(count: 1)),
(expected: 0, input: Data(count: 2)),
(expected: 0, input: Data(count: 3)),
(expected: 0, input: Data(count: 4)),
(expected: 0, input: Data(count: 5)),
(expected: 4294967295, input: Data([0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF])),
(expected: 4294967295, input: Data(count: 1) + Data([0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF])),
(expected: 14200, input: Data([0b0011_0111, 0b0111_1000])),
(expected: 14200, input: Data(count: 14) + Data([0b0011_0111, 0b0111_1000])),
(expected: 16702650, input: Data([0xFE, 0xDC, 0xBA])),
(expected: 16702650, input: Data(count: 14) + Data([0xFE, 0xDC, 0xBA]))
]
fileprivate let testSpecs_int32: [TestSpec<Int32>] = [
(expected: 0, input: Data()),
(expected: 0, input: Data(count: 1)),
(expected: 0, input: Data(count: 2)),
(expected: 0, input: Data(count: 3)),
(expected: 0, input: Data(count: 4)),
(expected: 0, input: Data(count: 5)),
(expected: -2147483647, input: Data([0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF])),
(expected: -2147483647, input: Data(count: 1) + Data([0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF])),
(expected: 2147483647, input: Data([0x00, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF])),
(expected: 2147483647, input: Data(count: 1) + Data([0x00, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF])),
(expected: 14200, input: Data([0b0011_0111, 0b0111_1000])),
(expected: 14200, input: Data(count: 14) + Data([0b0011_0111, 0b0111_1000])),
(expected: -14200, input: Data([0b1011_0111, 0b0111_1000])),
(expected: -14200, input: Data([0b1000_0000]) + Data(count: 13) + Data([0b0011_0111, 0b0111_1000])),
(expected: 16702650, input: Data([0xFE, 0xDC, 0xBA])),
(expected: 16702650, input: Data(count: 14) + Data([0xFE, 0xDC, 0xBA]))
]
fileprivate let testSpecs_uInt64: [TestSpec<UInt64>] = [
(expected: 0, input: Data()),
(expected: 0, input: Data(count: 1)),
(expected: 0, input: Data(count: 2)),
(expected: 0, input: Data(count: 3)),
(expected: 0, input: Data(count: 4)),
(expected: 0, input: Data(count: 5)),
(expected: 255, input: Data([0b1111_1111])),
(expected: 255, input: Data(count: 1) + Data([0b1111_1111])),
(expected: 14200, input: Data([0b0011_0111, 0b0111_1000])),
(expected: 14200, input: Data(count: 14) + Data([0b0011_0111, 0b0111_1000])),
(expected: 16702650, input: Data([0xFE, 0xDC, 0xBA])),
(expected: 16702650, input: Data(count: 14) + Data([0xFE, 0xDC, 0xBA])),
(expected: 280223976814164, input: Data([0xFE, 0xDC, 0xBA, 0x98, 0x76, 0x54])),
(expected: 280223976814164, input: Data(count: 14) + Data([0xFE, 0xDC, 0xBA, 0x98, 0x76, 0x54]))
]
class DecoderTest: XCTestCase {
private let bigEndianDecoder = Decoder(inputEndianness: .big)
private let littleEndianDecoder = Decoder(inputEndianness: .little)
func testDecode() {
for (expected, input) in testSpecs {
func testDecode_uInt16() {
for (expected, input) in testSpecs_uInt16 {
assertDecodedValue(expected, bigEndianDecoder.decode, data: input)
}
for (expected, input) in testSpecs {
for (expected, input) in testSpecs_uInt16 {
assertDecodedValue(
expected,
littleEndianDecoder.decode,
data: Data(input.reversed())
)
}
}
func testDecode_uInt32() {
for (expected, input) in testSpecs_uInt32 {
assertDecodedValue(expected, bigEndianDecoder.decode, data: input)
}
for (expected, input) in testSpecs_uInt32 {
assertDecodedValue(
expected,
littleEndianDecoder.decode,
data: Data(input.reversed())
)
}
}
func testDecode_uInt64() {
for (expected, input) in testSpecs_uInt64 {
assertDecodedValue(expected, bigEndianDecoder.decode, data: input)
}
for (expected, input) in testSpecs_uInt64 {
assertDecodedValue(
expected,
littleEndianDecoder.decode,
data: Data(input.reversed())
)
}
}
func testDecode_int32() {
for (expected, input) in testSpecs_int32 {
assertDecodedValue(expected, bigEndianDecoder.decode, data: input)
}
for (expected, input) in testSpecs_int32 {
assertDecodedValue(
expected,
littleEndianDecoder.decode,