From ba6467c7e1a8e039ffdc9d0ee1518a853ed59b03 Mon Sep 17 00:00:00 2001 From: raghavroy145 Date: Thu, 3 Apr 2025 18:15:59 +0100 Subject: [PATCH 1/2] Add Peek API for Multiple Integers Motivation: The current readMultipleIntegers methods are used to consume multiple integer values at once, but lack an equivalent nonmutating API. This can lead to unnecessary complexity when users want to inspect values without advancing readerIndex. THis patch introduces peekMultipleIntegers which uses the current readerIndex, improving safety. This extends previous work on peek methods (issue #2034, issue #2736). Modifications: Updated the generation script (.sh file) to produce peekMultipleIntegers variants for each arity of readMultipleIntegers. Added new tests mirroring the existing multi-read/write tests Result: Users can now inspect multiple integer values in a ByteBuffer without consuming them, enabling safer workflows. --- Sources/NIOCore/ByteBuffer-multi-int.swift | 269 +++++++++++++++++++++ Tests/NIOCoreTests/ByteBufferTest.swift | 156 ++++++++++++ dev/generate-bytebuffer-multi-int.sh | 26 ++ 3 files changed, 451 insertions(+) diff --git a/Sources/NIOCore/ByteBuffer-multi-int.swift b/Sources/NIOCore/ByteBuffer-multi-int.swift index 175f7d3fc6d..f9750c91e50 100644 --- a/Sources/NIOCore/ByteBuffer-multi-int.swift +++ b/Sources/NIOCore/ByteBuffer-multi-int.swift @@ -53,6 +53,16 @@ extension ByteBuffer { } } + @inlinable + @_alwaysEmitIntoClient + public func peekMultipleIntegers( + endianness: Endianness = .big, + as: (T1, T2).Type = (T1, T2).self + ) -> (T1, T2)? { + var copy = self + return copy.readMultipleIntegers(endianness: endianness, as: `as`) + } + @inlinable @_alwaysEmitIntoClient @discardableResult @@ -133,6 +143,16 @@ extension ByteBuffer { } } + @inlinable + @_alwaysEmitIntoClient + public func peekMultipleIntegers( + endianness: Endianness = .big, + as: (T1, T2, T3).Type = (T1, T2, T3).self + ) -> (T1, T2, T3)? { + var copy = self + return copy.readMultipleIntegers(endianness: endianness, as: `as`) + } + @inlinable @_alwaysEmitIntoClient @discardableResult @@ -228,6 +248,18 @@ extension ByteBuffer { } } + @inlinable + @_alwaysEmitIntoClient + public func peekMultipleIntegers< + T1: FixedWidthInteger, + T2: FixedWidthInteger, + T3: FixedWidthInteger, + T4: FixedWidthInteger + >(endianness: Endianness = .big, as: (T1, T2, T3, T4).Type = (T1, T2, T3, T4).self) -> (T1, T2, T3, T4)? { + var copy = self + return copy.readMultipleIntegers(endianness: endianness, as: `as`) + } + @inlinable @_alwaysEmitIntoClient @discardableResult @@ -346,6 +378,20 @@ extension ByteBuffer { } } + @inlinable + @_alwaysEmitIntoClient + public func peekMultipleIntegers< + T1: FixedWidthInteger, + T2: FixedWidthInteger, + T3: FixedWidthInteger, + T4: FixedWidthInteger, + T5: FixedWidthInteger + >(endianness: Endianness = .big, as: (T1, T2, T3, T4, T5).Type = (T1, T2, T3, T4, T5).self) -> (T1, T2, T3, T4, T5)? + { + var copy = self + return copy.readMultipleIntegers(endianness: endianness, as: `as`) + } + @inlinable @_alwaysEmitIntoClient @discardableResult @@ -484,6 +530,23 @@ extension ByteBuffer { } } + @inlinable + @_alwaysEmitIntoClient + public func peekMultipleIntegers< + T1: FixedWidthInteger, + T2: FixedWidthInteger, + T3: FixedWidthInteger, + T4: FixedWidthInteger, + T5: FixedWidthInteger, + T6: FixedWidthInteger + >( + endianness: Endianness = .big, + as: (T1, T2, T3, T4, T5, T6).Type = (T1, T2, T3, T4, T5, T6).self + ) -> (T1, T2, T3, T4, T5, T6)? { + var copy = self + return copy.readMultipleIntegers(endianness: endianness, as: `as`) + } + @inlinable @_alwaysEmitIntoClient @discardableResult @@ -637,6 +700,24 @@ extension ByteBuffer { } } + @inlinable + @_alwaysEmitIntoClient + public func peekMultipleIntegers< + T1: FixedWidthInteger, + T2: FixedWidthInteger, + T3: FixedWidthInteger, + T4: FixedWidthInteger, + T5: FixedWidthInteger, + T6: FixedWidthInteger, + T7: FixedWidthInteger + >( + endianness: Endianness = .big, + as: (T1, T2, T3, T4, T5, T6, T7).Type = (T1, T2, T3, T4, T5, T6, T7).self + ) -> (T1, T2, T3, T4, T5, T6, T7)? { + var copy = self + return copy.readMultipleIntegers(endianness: endianness, as: `as`) + } + @inlinable @_alwaysEmitIntoClient @discardableResult @@ -805,6 +886,25 @@ extension ByteBuffer { } } + @inlinable + @_alwaysEmitIntoClient + public func peekMultipleIntegers< + T1: FixedWidthInteger, + T2: FixedWidthInteger, + T3: FixedWidthInteger, + T4: FixedWidthInteger, + T5: FixedWidthInteger, + T6: FixedWidthInteger, + T7: FixedWidthInteger, + T8: FixedWidthInteger + >( + endianness: Endianness = .big, + as: (T1, T2, T3, T4, T5, T6, T7, T8).Type = (T1, T2, T3, T4, T5, T6, T7, T8).self + ) -> (T1, T2, T3, T4, T5, T6, T7, T8)? { + var copy = self + return copy.readMultipleIntegers(endianness: endianness, as: `as`) + } + @inlinable @_alwaysEmitIntoClient @discardableResult @@ -989,6 +1089,26 @@ extension ByteBuffer { } } + @inlinable + @_alwaysEmitIntoClient + public func peekMultipleIntegers< + T1: FixedWidthInteger, + T2: FixedWidthInteger, + T3: FixedWidthInteger, + T4: FixedWidthInteger, + T5: FixedWidthInteger, + T6: FixedWidthInteger, + T7: FixedWidthInteger, + T8: FixedWidthInteger, + T9: FixedWidthInteger + >( + endianness: Endianness = .big, + as: (T1, T2, T3, T4, T5, T6, T7, T8, T9).Type = (T1, T2, T3, T4, T5, T6, T7, T8, T9).self + ) -> (T1, T2, T3, T4, T5, T6, T7, T8, T9)? { + var copy = self + return copy.readMultipleIntegers(endianness: endianness, as: `as`) + } + @inlinable @_alwaysEmitIntoClient @discardableResult @@ -1188,6 +1308,27 @@ extension ByteBuffer { } } + @inlinable + @_alwaysEmitIntoClient + public func peekMultipleIntegers< + T1: FixedWidthInteger, + T2: FixedWidthInteger, + T3: FixedWidthInteger, + T4: FixedWidthInteger, + T5: FixedWidthInteger, + T6: FixedWidthInteger, + T7: FixedWidthInteger, + T8: FixedWidthInteger, + T9: FixedWidthInteger, + T10: FixedWidthInteger + >( + endianness: Endianness = .big, + as: (T1, T2, T3, T4, T5, T6, T7, T8, T9, T10).Type = (T1, T2, T3, T4, T5, T6, T7, T8, T9, T10).self + ) -> (T1, T2, T3, T4, T5, T6, T7, T8, T9, T10)? { + var copy = self + return copy.readMultipleIntegers(endianness: endianness, as: `as`) + } + @inlinable @_alwaysEmitIntoClient @discardableResult @@ -1403,6 +1544,28 @@ extension ByteBuffer { } } + @inlinable + @_alwaysEmitIntoClient + public func peekMultipleIntegers< + T1: FixedWidthInteger, + T2: FixedWidthInteger, + T3: FixedWidthInteger, + T4: FixedWidthInteger, + T5: FixedWidthInteger, + T6: FixedWidthInteger, + T7: FixedWidthInteger, + T8: FixedWidthInteger, + T9: FixedWidthInteger, + T10: FixedWidthInteger, + T11: FixedWidthInteger + >( + endianness: Endianness = .big, + as: (T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11).Type = (T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11).self + ) -> (T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11)? { + var copy = self + return copy.readMultipleIntegers(endianness: endianness, as: `as`) + } + @inlinable @_alwaysEmitIntoClient @discardableResult @@ -1635,6 +1798,31 @@ extension ByteBuffer { } } + @inlinable + @_alwaysEmitIntoClient + public func peekMultipleIntegers< + T1: FixedWidthInteger, + T2: FixedWidthInteger, + T3: FixedWidthInteger, + T4: FixedWidthInteger, + T5: FixedWidthInteger, + T6: FixedWidthInteger, + T7: FixedWidthInteger, + T8: FixedWidthInteger, + T9: FixedWidthInteger, + T10: FixedWidthInteger, + T11: FixedWidthInteger, + T12: FixedWidthInteger + >( + endianness: Endianness = .big, + as: (T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, T12).Type = ( + T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, T12 + ).self + ) -> (T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, T12)? { + var copy = self + return copy.readMultipleIntegers(endianness: endianness, as: `as`) + } + @inlinable @_alwaysEmitIntoClient @discardableResult @@ -1885,6 +2073,32 @@ extension ByteBuffer { } } + @inlinable + @_alwaysEmitIntoClient + public func peekMultipleIntegers< + T1: FixedWidthInteger, + T2: FixedWidthInteger, + T3: FixedWidthInteger, + T4: FixedWidthInteger, + T5: FixedWidthInteger, + T6: FixedWidthInteger, + T7: FixedWidthInteger, + T8: FixedWidthInteger, + T9: FixedWidthInteger, + T10: FixedWidthInteger, + T11: FixedWidthInteger, + T12: FixedWidthInteger, + T13: FixedWidthInteger + >( + endianness: Endianness = .big, + as: (T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, T12, T13).Type = ( + T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, T12, T13 + ).self + ) -> (T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, T12, T13)? { + var copy = self + return copy.readMultipleIntegers(endianness: endianness, as: `as`) + } + @inlinable @_alwaysEmitIntoClient @discardableResult @@ -2150,6 +2364,33 @@ extension ByteBuffer { } } + @inlinable + @_alwaysEmitIntoClient + public func peekMultipleIntegers< + T1: FixedWidthInteger, + T2: FixedWidthInteger, + T3: FixedWidthInteger, + T4: FixedWidthInteger, + T5: FixedWidthInteger, + T6: FixedWidthInteger, + T7: FixedWidthInteger, + T8: FixedWidthInteger, + T9: FixedWidthInteger, + T10: FixedWidthInteger, + T11: FixedWidthInteger, + T12: FixedWidthInteger, + T13: FixedWidthInteger, + T14: FixedWidthInteger + >( + endianness: Endianness = .big, + as: (T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, T12, T13, T14).Type = ( + T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, T12, T13, T14 + ).self + ) -> (T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, T12, T13, T14)? { + var copy = self + return copy.readMultipleIntegers(endianness: endianness, as: `as`) + } + @inlinable @_alwaysEmitIntoClient @discardableResult @@ -2430,6 +2671,34 @@ extension ByteBuffer { } } + @inlinable + @_alwaysEmitIntoClient + public func peekMultipleIntegers< + T1: FixedWidthInteger, + T2: FixedWidthInteger, + T3: FixedWidthInteger, + T4: FixedWidthInteger, + T5: FixedWidthInteger, + T6: FixedWidthInteger, + T7: FixedWidthInteger, + T8: FixedWidthInteger, + T9: FixedWidthInteger, + T10: FixedWidthInteger, + T11: FixedWidthInteger, + T12: FixedWidthInteger, + T13: FixedWidthInteger, + T14: FixedWidthInteger, + T15: FixedWidthInteger + >( + endianness: Endianness = .big, + as: (T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, T12, T13, T14, T15).Type = ( + T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, T12, T13, T14, T15 + ).self + ) -> (T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, T12, T13, T14, T15)? { + var copy = self + return copy.readMultipleIntegers(endianness: endianness, as: `as`) + } + @inlinable @_alwaysEmitIntoClient @discardableResult diff --git a/Tests/NIOCoreTests/ByteBufferTest.swift b/Tests/NIOCoreTests/ByteBufferTest.swift index 2d8564e91f2..1d581c24988 100644 --- a/Tests/NIOCoreTests/ByteBufferTest.swift +++ b/Tests/NIOCoreTests/ByteBufferTest.swift @@ -3765,6 +3765,162 @@ extension ByteBufferTest { XCTAssertEqual(0, self.buf.readableBytes) } + func testPeekAndWriteMultipleIntegers() { + // This test mirrors 'testReadAndWriteMultipleIntegers' but uses peekMultipleIntegers + for endianness in [Endianness.little, .big] { + let v1: UInt8 = .random(in: .min ... .max) + let v2: UInt16 = .random(in: .min ... .max) + let v3: UInt32 = .random(in: .min ... .max) + let v4: UInt64 = .random(in: .min ... .max) + let v5: UInt64 = .random(in: .min ... .max) + let v6: UInt32 = .random(in: .min ... .max) + let v7: UInt16 = .random(in: .min ... .max) + let v8: UInt8 = .random(in: .min ... .max) + let v9: UInt16 = .random(in: .min ... .max) + let v10: UInt32 = .random(in: .min ... .max) + + let startWriterIndex = self.buf.writerIndex + let written = self.buf.writeMultipleIntegers( + v1, + v2, + v3, + v4, + v5, + v6, + v7, + v8, + v9, + v10, + endianness: endianness, + as: (UInt8, UInt16, UInt32, UInt64, UInt64, UInt32, UInt16, UInt8, UInt16, UInt32).self + ) + XCTAssertEqual(startWriterIndex + written, self.buf.writerIndex) + XCTAssertEqual(written, self.buf.readableBytes) + + // Check peek does not advance readerIndex + let startReadable = self.buf.readableBytes + let peeked = self.buf.peekMultipleIntegers( + endianness: endianness, + as: (UInt8, UInt16, UInt32, UInt64, UInt64, UInt32, UInt16, UInt8, UInt16, UInt32).self + ) + XCTAssertNotNil(peeked, "peekMultipleIntegers should succeed.") + XCTAssertEqual(startReadable, self.buf.readableBytes, "Peeking should not consume any bytes.") + + XCTAssertEqual(peeked?.0, v1, "endianness: \(endianness)") + XCTAssertEqual(peeked?.1, v2, "endianness: \(endianness)") + XCTAssertEqual(peeked?.2, v3, "endianness: \(endianness)") + XCTAssertEqual(peeked?.3, v4, "endianness: \(endianness)") + XCTAssertEqual(peeked?.4, v5, "endianness: \(endianness)") + XCTAssertEqual(peeked?.5, v6, "endianness: \(endianness)") + XCTAssertEqual(peeked?.6, v7, "endianness: \(endianness)") + XCTAssertEqual(peeked?.7, v8, "endianness: \(endianness)") + XCTAssertEqual(peeked?.8, v9, "endianness: \(endianness)") + XCTAssertEqual(peeked?.9, v10, "endianness: \(endianness)") + + let result = self.buf.readMultipleIntegers( + endianness: endianness, + as: (UInt8, UInt16, UInt32, UInt64, UInt64, UInt32, UInt16, UInt8, UInt16, UInt32).self + ) + XCTAssertNotNil(result, "Expected to successfully read after peeking.") + XCTAssertEqual(result?.0, v1, "endianness: \(endianness)") + XCTAssertEqual(result?.1, v2, "endianness: \(endianness)") + XCTAssertEqual(result?.2, v3, "endianness: \(endianness)") + XCTAssertEqual(result?.3, v4, "endianness: \(endianness)") + XCTAssertEqual(result?.4, v5, "endianness: \(endianness)") + XCTAssertEqual(result?.5, v6, "endianness: \(endianness)") + XCTAssertEqual(result?.6, v7, "endianness: \(endianness)") + XCTAssertEqual(result?.7, v8, "endianness: \(endianness)") + XCTAssertEqual(result?.8, v9, "endianness: \(endianness)") + XCTAssertEqual(result?.9, v10, "endianness: \(endianness)") + XCTAssertEqual(0, self.buf.readableBytes) + } + } + + func testAllByteBufferMultiByteVersionsPeek() { + // This test mirrors 'testAllByteBufferMultiByteVersions' but using peekMultipleIntegers + let i = UInt8(86) + self.buf.writeMultipleIntegers(i, i) + self.buf.writeMultipleIntegers(i, i, i) + self.buf.writeMultipleIntegers(i, i, i, i) + self.buf.writeMultipleIntegers(i, i, i, i, i) + self.buf.writeMultipleIntegers(i, i, i, i, i, i) + self.buf.writeMultipleIntegers(i, i, i, i, i, i, i) + self.buf.writeMultipleIntegers(i, i, i, i, i, i, i, i) + self.buf.writeMultipleIntegers(i, i, i, i, i, i, i, i, i) + self.buf.writeMultipleIntegers(i, i, i, i, i, i, i, i, i, i) + self.buf.writeMultipleIntegers(i, i, i, i, i, i, i, i, i, i, i) + self.buf.writeMultipleIntegers(i, i, i, i, i, i, i, i, i, i, i, i) + self.buf.writeMultipleIntegers(i, i, i, i, i, i, i, i, i, i, i, i, i) + self.buf.writeMultipleIntegers(i, i, i, i, i, i, i, i, i, i, i, i, i, i) + self.buf.writeMultipleIntegers(i, i, i, i, i, i, i, i, i, i, i, i, i, i, i) + + XCTAssertEqual(Array(repeating: UInt8(86), count: 119), Array(self.buf.readableBytesView)) + + let peek2 = self.buf.peekMultipleIntegers(as: (UInt8, UInt8).self) + XCTAssertNotNil(peek2, "Expected to peek 2 UInt8s.") + XCTAssertEqual( + Array(self.buf.readableBytesView), + Array(repeating: i, count: 119), + "No bytes should be consumed by peek." + ) + let offset2 = MemoryLayout.size * 2 + let peek3 = self.buf.getSlice(at: self.buf.readerIndex + offset2, length: 3)?.peekMultipleIntegers( + as: (UInt8, UInt8, UInt8).self + ) + XCTAssertNotNil(peek3, "Expected to peek 3 UInt8s from the next region.") + var values2 = self.buf.readMultipleIntegers(as: (UInt8, UInt8).self)! + var values3 = self.buf.readMultipleIntegers(as: (UInt8, UInt8, UInt8).self)! + var values4 = self.buf.readMultipleIntegers(as: (UInt8, UInt8, UInt8, UInt8).self)! + var values5 = self.buf.readMultipleIntegers(as: (UInt8, UInt8, UInt8, UInt8, UInt8).self)! + var values6 = self.buf.readMultipleIntegers(as: (UInt8, UInt8, UInt8, UInt8, UInt8, UInt8).self)! + var values7 = self.buf.readMultipleIntegers(as: (UInt8, UInt8, UInt8, UInt8, UInt8, UInt8, UInt8).self)! + var values8 = self.buf.readMultipleIntegers(as: (UInt8, UInt8, UInt8, UInt8, UInt8, UInt8, UInt8, UInt8).self)! + var values9 = self.buf.readMultipleIntegers( + as: (UInt8, UInt8, UInt8, UInt8, UInt8, UInt8, UInt8, UInt8, UInt8).self + )! + var values10 = self.buf.readMultipleIntegers( + as: (UInt8, UInt8, UInt8, UInt8, UInt8, UInt8, UInt8, UInt8, UInt8, UInt8).self + )! + var values11 = self.buf.readMultipleIntegers( + as: (UInt8, UInt8, UInt8, UInt8, UInt8, UInt8, UInt8, UInt8, UInt8, UInt8, UInt8).self + )! + var values12 = self.buf.readMultipleIntegers( + as: (UInt8, UInt8, UInt8, UInt8, UInt8, UInt8, UInt8, UInt8, UInt8, UInt8, UInt8, UInt8).self + )! + var values13 = self.buf.readMultipleIntegers( + as: (UInt8, UInt8, UInt8, UInt8, UInt8, UInt8, UInt8, UInt8, UInt8, UInt8, UInt8, UInt8, UInt8).self + )! + var values14 = self.buf.readMultipleIntegers( + as: (UInt8, UInt8, UInt8, UInt8, UInt8, UInt8, UInt8, UInt8, UInt8, UInt8, UInt8, UInt8, UInt8, UInt8).self + )! + var values15 = self.buf.readMultipleIntegers( + as: ( + UInt8, UInt8, UInt8, UInt8, UInt8, UInt8, UInt8, UInt8, UInt8, UInt8, UInt8, UInt8, UInt8, UInt8, UInt8 + ).self + )! + + let iArray2 = withUnsafeBytes(of: &values2, { Array($0) }) + XCTAssertEqual([i, i], iArray2) + XCTAssertEqual([i, i, i], withUnsafeBytes(of: &values3, { Array($0) })) + XCTAssertEqual([i, i, i, i], withUnsafeBytes(of: &values4, { Array($0) })) + XCTAssertEqual([i, i, i, i, i], withUnsafeBytes(of: &values5, { Array($0) })) + XCTAssertEqual([i, i, i, i, i, i], withUnsafeBytes(of: &values6, { Array($0) })) + XCTAssertEqual([i, i, i, i, i, i, i], withUnsafeBytes(of: &values7, { Array($0) })) + XCTAssertEqual([i, i, i, i, i, i, i, i], withUnsafeBytes(of: &values8, { Array($0) })) + XCTAssertEqual([i, i, i, i, i, i, i, i, i], withUnsafeBytes(of: &values9, { Array($0) })) + XCTAssertEqual([i, i, i, i, i, i, i, i, i, i], withUnsafeBytes(of: &values10, { Array($0) })) + XCTAssertEqual([i, i, i, i, i, i, i, i, i, i, i], withUnsafeBytes(of: &values11, { Array($0) })) + XCTAssertEqual([i, i, i, i, i, i, i, i, i, i, i, i], withUnsafeBytes(of: &values12, { Array($0) })) + XCTAssertEqual([i, i, i, i, i, i, i, i, i, i, i, i, i], withUnsafeBytes(of: &values13, { Array($0) })) + XCTAssertEqual([i, i, i, i, i, i, i, i, i, i, i, i, i, i], withUnsafeBytes(of: &values14, { Array($0) })) + XCTAssertEqual( + [i, i, i, i, i, i, i, i, i, i, i, i, i, i, i], + withUnsafeBytes(of: &values15, { Array($0) }) + ) + + XCTAssertEqual(0, self.buf.readableBytes, "Buffer should be fully consumed after all reads.") + } + func testByteBufferEncode() throws { let encoder = JSONEncoder() let hello = "Hello, world!" diff --git a/dev/generate-bytebuffer-multi-int.sh b/dev/generate-bytebuffer-multi-int.sh index a225bcb56f1..a2a9f184c38 100755 --- a/dev/generate-bytebuffer-multi-int.sh +++ b/dev/generate-bytebuffer-multi-int.sh @@ -79,6 +79,32 @@ function gen() { echo " }" echo + #PEEK + echo " @inlinable" + echo " @_alwaysEmitIntoClient" + echo -n " public func peekMultipleIntegers(" + echo -n "endianness: Endianness = .big, as: (T1" + for n in $(seq 2 "$how_many"); do + echo -n ", T$n" + done + echo -n ").Type = (T1" + for n in $(seq 2 "$how_many"); do + echo -n ", T$n" + done + echo -n ").self) -> (T1" + for n in $(seq 2 "$how_many"); do + echo -n ", T$n" + done + echo ")? {" + echo " var copy = self" + echo " return copy.readMultipleIntegers(endianness: endianness, as: \`as\`)" + echo " }" + echo + # WRITE echo " @inlinable" echo " @_alwaysEmitIntoClient" From 533ac9c7d72e1ae80344f8b43ca45081e82ff9fc Mon Sep 17 00:00:00 2001 From: raghavroy145 Date: Fri, 4 Apr 2025 17:08:39 +0100 Subject: [PATCH 2/2] Resolved review comments: test additions + nits --- Tests/NIOCoreTests/ByteBufferTest.swift | 5 +++++ dev/generate-bytebuffer-multi-int.sh | 2 +- 2 files changed, 6 insertions(+), 1 deletion(-) diff --git a/Tests/NIOCoreTests/ByteBufferTest.swift b/Tests/NIOCoreTests/ByteBufferTest.swift index 1d581c24988..9d659bcf947 100644 --- a/Tests/NIOCoreTests/ByteBufferTest.swift +++ b/Tests/NIOCoreTests/ByteBufferTest.swift @@ -3858,6 +3858,8 @@ extension ByteBufferTest { let peek2 = self.buf.peekMultipleIntegers(as: (UInt8, UInt8).self) XCTAssertNotNil(peek2, "Expected to peek 2 UInt8s.") + XCTAssertEqual(peek2?.0, i, "First value mismatch in peek2") + XCTAssertEqual(peek2?.1, i, "Second value mismatch in peek2") XCTAssertEqual( Array(self.buf.readableBytesView), Array(repeating: i, count: 119), @@ -3868,6 +3870,9 @@ extension ByteBufferTest { as: (UInt8, UInt8, UInt8).self ) XCTAssertNotNil(peek3, "Expected to peek 3 UInt8s from the next region.") + XCTAssertEqual(peek3?.0, i, "First value mismatch in peek3") + XCTAssertEqual(peek3?.1, i, "Second value mismatch in peek3") + XCTAssertEqual(peek3?.2, i, "Third value mismatch in peek3") var values2 = self.buf.readMultipleIntegers(as: (UInt8, UInt8).self)! var values3 = self.buf.readMultipleIntegers(as: (UInt8, UInt8, UInt8).self)! var values4 = self.buf.readMultipleIntegers(as: (UInt8, UInt8, UInt8, UInt8).self)! diff --git a/dev/generate-bytebuffer-multi-int.sh b/dev/generate-bytebuffer-multi-int.sh index a2a9f184c38..ac57635452f 100755 --- a/dev/generate-bytebuffer-multi-int.sh +++ b/dev/generate-bytebuffer-multi-int.sh @@ -79,7 +79,7 @@ function gen() { echo " }" echo - #PEEK + # PEEK echo " @inlinable" echo " @_alwaysEmitIntoClient" echo -n " public func peekMultipleIntegers