Skip to content

Commit eeaaf3e

Browse files
committed
Add read InlineArray + tests
1 parent adfa636 commit eeaaf3e

File tree

2 files changed

+83
-0
lines changed

2 files changed

+83
-0
lines changed

Sources/NIOCore/ByteBuffer-aux.swift

Lines changed: 42 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -58,6 +58,48 @@ extension ByteBuffer {
5858
return result
5959
}
6060

61+
#if compiler(>=6.2) && !canImport(Darwin)
62+
@inlinable
63+
public mutating func readInlineArray<
64+
let count: Int,
65+
IntegerType: FixedWidthInteger
66+
>(
67+
endianness: Endianness = .big,
68+
as: InlineArray<count, IntegerType>.Type = InlineArray<count, IntegerType>.self
69+
) -> InlineArray<count, IntegerType>? {
70+
let length = MemoryLayout<IntegerType>.size
71+
let bytesRequired = length &* count
72+
73+
guard self.readableBytes >= bytesRequired else {
74+
return nil
75+
}
76+
77+
return self.readWithUnsafeReadableBytes {
78+
ptr -> (Int, InlineArray<count, IntegerType>) in
79+
assert(ptr.count >= bytesRequired)
80+
let values: InlineArray<count, IntegerType> = InlineArray { index in
81+
switch endianness {
82+
case .big:
83+
return IntegerType(
84+
bigEndian: ptr.load(
85+
fromByteOffset: index &* length,
86+
as: IntegerType.self
87+
)
88+
)
89+
case .little:
90+
return IntegerType(
91+
littleEndian: ptr.load(
92+
fromByteOffset: index &* length,
93+
as: IntegerType.self
94+
)
95+
)
96+
}
97+
}
98+
return (bytesRequired, values)
99+
}
100+
}
101+
#endif
102+
61103
/// Returns the Bytes at the current reader index without advancing it.
62104
///
63105
/// This method is equivalent to calling `getBytes(at: readerIndex, ...)`

Tests/NIOCoreTests/ByteBufferTest.swift

Lines changed: 41 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -3932,6 +3932,47 @@ extension ByteBufferTest {
39323932
XCTAssertEqual(0, self.buf.readableBytes, "Buffer should be fully consumed after all reads.")
39333933
}
39343934

3935+
#if compiler(>=6.2) && !canImport(Darwin)
3936+
func testReadInlineArrayOfUInt8() throws {
3937+
let bytes = (0..<10).map { _ in UInt8.random(in: .min ... .max) }
3938+
3939+
let startWriterIndex = self.buf.writerIndex
3940+
let written = self.buf.writeBytes(bytes)
3941+
XCTAssertEqual(startWriterIndex + written, self.buf.writerIndex)
3942+
XCTAssertEqual(written, self.buf.readableBytes)
3943+
3944+
let result = try XCTUnwrap(
3945+
self.buf.readInlineArray(as: InlineArray<10, UInt8>.self)
3946+
)
3947+
XCTAssertEqual(10, result.count)
3948+
for idx in result.indices {
3949+
XCTAssertEqual(bytes[idx], result[idx])
3950+
}
3951+
XCTAssertEqual(0, self.buf.readableBytes)
3952+
}
3953+
3954+
func testReadInlineArrayOfUInt64() throws {
3955+
let bytes = (0..<10).map { _ in UInt64.random(in: .min ... .max) }
3956+
3957+
let startWriterIndex = self.buf.writerIndex
3958+
var written = 0
3959+
for byte in bytes {
3960+
written += self.buf.writeInteger(byte)
3961+
}
3962+
XCTAssertEqual(startWriterIndex + written, self.buf.writerIndex)
3963+
XCTAssertEqual(written, self.buf.readableBytes)
3964+
3965+
let result = try XCTUnwrap(
3966+
self.buf.readInlineArray(as: InlineArray<10, UInt64>.self)
3967+
)
3968+
XCTAssertEqual(10, result.count)
3969+
for idx in result.indices {
3970+
XCTAssertEqual(bytes[idx], result[idx])
3971+
}
3972+
XCTAssertEqual(0, self.buf.readableBytes)
3973+
}
3974+
#endif
3975+
39353976
func testByteBufferEncode() throws {
39363977
let encoder = JSONEncoder()
39373978
let hello = "Hello, world!"

0 commit comments

Comments
 (0)