From 6d46e85307e714c2a1766e73e3d02f425acf5732 Mon Sep 17 00:00:00 2001 From: Dimitri Bouniol Date: Sat, 24 Feb 2024 02:07:41 -0800 Subject: [PATCH 1/2] Simplified raw memory access helpers --- Sources/Bytes/Colletion+Casting.swift | 24 ++++++++++-------------- Tests/BytesTests/IntegerTests.swift | 6 ++++++ 2 files changed, 16 insertions(+), 14 deletions(-) diff --git a/Sources/Bytes/Colletion+Casting.swift b/Sources/Bytes/Colletion+Casting.swift index d7578c9..13fe419 100644 --- a/Sources/Bytes/Colletion+Casting.swift +++ b/Sources/Bytes/Colletion+Casting.swift @@ -39,21 +39,17 @@ extension BidirectionalCollection where Element == Byte { public func casting() throws -> R { try canBeCasted(to: R.self) - guard - let result = self.withContiguousStorageIfAvailable({ - $0.withUnsafeBytes { - $0.baseAddress!.assumingMemoryBound(to: R.self).pointee - } - }) - else { - guard self.count <= 4*1024 else { // If bytes is less than 4KB, then perform a copy first - throw BytesError.contiguousMemoryUnavailable(type: "\(Self.self)") - } - return Bytes(self).withUnsafeBytes { - $0.baseAddress!.assumingMemoryBound(to: R.self).pointee - } + if let result = self.withContiguousStorageIfAvailable({ + $0.withUnsafeBytes { $0.loadUnaligned(as: R.self) } + }) { + return result } - return result + + /// If bytes is less than 4KB, then perform a copy first + guard self.count <= 4*1024 + else { throw BytesError.contiguousMemoryUnavailable(type: "\(Self.self)") } + + return Bytes(self).withUnsafeBytes { $0.loadUnaligned(as: R.self) } } /// Create a new Bytes sequence from the memory occupied by the passed in value. diff --git a/Tests/BytesTests/IntegerTests.swift b/Tests/BytesTests/IntegerTests.swift index 7404fa9..1815adf 100644 --- a/Tests/BytesTests/IntegerTests.swift +++ b/Tests/BytesTests/IntegerTests.swift @@ -32,6 +32,12 @@ final class IntegerTests: XCTestCase { XCTAssertEqual(try Int64(littleEndianBytes: [0x11, 0x32, 0x54, 0x76, 0x98, 0xba, 0xdc, 0xfe]), Int64(-0x0123456789abcdef)) } + func testUnalignedMemoryAccess() throws { + let bytes: Bytes = [0x0, 0x0, 0x0, 0x01, 0x23, 0x45, 0x67, 0x0] + + XCTAssertEqual(try UInt32(bigEndianBytes: bytes.dropFirst(3).dropLast()), UInt32(0x01234567)) + } + func testInvalidBytes() throws { XCTAssertThrowsError(try UInt8(bigEndianBytes: [])) { BytesError.testInvalidMemorySize($0, targetSize: 1, targetType: "UInt8", actualSize: 0) From 18e1f08f2286035037afc2c887621ee65af23f4b Mon Sep 17 00:00:00 2001 From: Dimitri Bouniol Date: Sat, 24 Feb 2024 02:08:16 -0800 Subject: [PATCH 2/2] Updated README with latest release version info --- README.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/README.md b/README.md index e3ef1d0..bee85e1 100644 --- a/README.md +++ b/README.md @@ -26,7 +26,7 @@ Please check the [releases](https://github.com/mochidev/Bytes/releases) for reco ```swift dependencies: [ - .package(url: "https://github.com/mochidev/Bytes.git", .upToNextMinor(from: "0.2.2")), + .package(url: "https://github.com/mochidev/Bytes.git", .upToNextMinor(from: "0.3.1")), ], ... targets: [