Swift 6.4 migration and exhancements #1
@@ -41,13 +41,15 @@ extension File {
|
|||||||
|
|
||||||
/// Reads up to `length` bytes and returns them.
|
/// Reads up to `length` bytes and returns them.
|
||||||
public func read(length: Int) throws(PlaydateError) -> [UInt8] {
|
public func read(length: Int) throws(PlaydateError) -> [UInt8] {
|
||||||
var bytes = [UInt8](repeating: 0, count: length)
|
try [UInt8](capacity: length) { output throws(PlaydateError) in
|
||||||
let result = bytes.withUnsafeMutableBytes { buffer in
|
let result = output.withUnsafeMutableBufferPointer { buffer, initializedCount in
|
||||||
fileAPI.pointee.read.unsafelyUnwrapped(pointer, buffer.baseAddress, UInt32(buffer.count))
|
let result = fileAPI.pointee.read.unsafelyUnwrapped(
|
||||||
|
pointer, buffer.baseAddress, UInt32(buffer.count))
|
||||||
|
initializedCount = max(Int(result), 0)
|
||||||
|
return result
|
||||||
}
|
}
|
||||||
if result < 0 { throw lastFileError() }
|
if result < 0 { throw lastFileError() }
|
||||||
bytes.removeLast(length - Int(result))
|
}
|
||||||
return bytes
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Writes the bytes to the file. Returns the number of bytes written.
|
/// Writes the bytes to the file. Returns the number of bytes written.
|
||||||
|
|||||||
@@ -164,15 +164,17 @@ extension Network {
|
|||||||
|
|
||||||
/// Reads up to `length` available response bytes.
|
/// Reads up to `length` available response bytes.
|
||||||
public func read(length: Int) throws(NetError) -> [UInt8] {
|
public func read(length: Int) throws(NetError) -> [UInt8] {
|
||||||
var bytes = [UInt8](repeating: 0, count: length)
|
try [UInt8](capacity: length) { output throws(NetError) in
|
||||||
let result = bytes.withUnsafeMutableBytes { buffer in
|
let result = output.withUnsafeMutableBufferPointer { buffer, initializedCount in
|
||||||
httpAPI.pointee.read.unsafelyUnwrapped(pointer, buffer.baseAddress, UInt32(buffer.count))
|
let result = httpAPI.pointee.read.unsafelyUnwrapped(
|
||||||
|
pointer, buffer.baseAddress, UInt32(buffer.count))
|
||||||
|
initializedCount = max(Int(result), 0)
|
||||||
|
return result
|
||||||
}
|
}
|
||||||
if result < 0 {
|
if result < 0 {
|
||||||
throw NetError(rawValue: result) ?? .unknown
|
throw NetError(rawValue: result) ?? .unknown
|
||||||
}
|
}
|
||||||
bytes.removeLast(length - Int(result))
|
}
|
||||||
return bytes
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Closes the connection.
|
/// Closes the connection.
|
||||||
|
|||||||
@@ -124,15 +124,16 @@ extension Network {
|
|||||||
|
|
||||||
/// Reads up to `length` bytes, waiting up to the read timeout.
|
/// Reads up to `length` bytes, waiting up to the read timeout.
|
||||||
public func read(length: Int) throws(NetError) -> [UInt8] {
|
public func read(length: Int) throws(NetError) -> [UInt8] {
|
||||||
var bytes = [UInt8](repeating: 0, count: length)
|
try [UInt8](capacity: length) { output throws(NetError) in
|
||||||
let result = bytes.withUnsafeMutableBytes { buffer in
|
let result = output.withUnsafeMutableBufferPointer { buffer, initializedCount in
|
||||||
tcpAPI.pointee.read.unsafelyUnwrapped(pointer, buffer.baseAddress, buffer.count)
|
let result = tcpAPI.pointee.read.unsafelyUnwrapped(pointer, buffer.baseAddress, buffer.count)
|
||||||
|
initializedCount = max(Int(result), 0)
|
||||||
|
return result
|
||||||
}
|
}
|
||||||
if result < 0 {
|
if result < 0 {
|
||||||
throw NetError(rawValue: result) ?? .unknown
|
throw NetError(rawValue: result) ?? .unknown
|
||||||
}
|
}
|
||||||
bytes.removeLast(length - Int(result))
|
}
|
||||||
return bytes
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Writes the bytes to the connection. Returns the number of bytes
|
/// Writes the bytes to the connection. Returns the number of bytes
|
||||||
|
|||||||
@@ -35,6 +35,9 @@ enum Mock {
|
|||||||
nonisolated(unsafe) static var buttonState: (current: UInt32, pushed: UInt32, released: UInt32) = (0, 0, 0)
|
nonisolated(unsafe) static var buttonState: (current: UInt32, pushed: UInt32, released: UInt32) = (0, 0, 0)
|
||||||
/// The 16 bytes behind the last pattern `LCDColor` seen by a stub.
|
/// The 16 bytes behind the last pattern `LCDColor` seen by a stub.
|
||||||
nonisolated(unsafe) static var patternBytes: [UInt8] = []
|
nonisolated(unsafe) static var patternBytes: [UInt8] = []
|
||||||
|
/// Caps the bytes a file read returns (0 = end of file, negative =
|
||||||
|
/// error); `nil` fills the whole request.
|
||||||
|
nonisolated(unsafe) static var fileReadLimit: Int32?
|
||||||
/// Userdata stored per sprite / menu item, as the OS would keep it.
|
/// Userdata stored per sprite / menu item, as the OS would keep it.
|
||||||
nonisolated(unsafe) static var spriteUserdata: [OpaquePointer: UnsafeMutableRawPointer] = [:]
|
nonisolated(unsafe) static var spriteUserdata: [OpaquePointer: UnsafeMutableRawPointer] = [:]
|
||||||
nonisolated(unsafe) static var menuUserdata: [OpaquePointer: UnsafeMutableRawPointer] = [:]
|
nonisolated(unsafe) static var menuUserdata: [OpaquePointer: UnsafeMutableRawPointer] = [:]
|
||||||
@@ -83,6 +86,7 @@ enum Mock {
|
|||||||
events = []
|
events = []
|
||||||
buttonState = (0, 0, 0)
|
buttonState = (0, 0, 0)
|
||||||
patternBytes = []
|
patternBytes = []
|
||||||
|
fileReadLimit = nil
|
||||||
spriteUserdata = [:]
|
spriteUserdata = [:]
|
||||||
menuUserdata = [:]
|
menuUserdata = [:]
|
||||||
menuCallback = nil
|
menuCallback = nil
|
||||||
@@ -400,9 +404,10 @@ enum Mock {
|
|||||||
return 0
|
return 0
|
||||||
}
|
}
|
||||||
fileAPI.pointee.read = { _, buffer, length in
|
fileAPI.pointee.read = { _, buffer, length in
|
||||||
memset(buffer, 0xAB, Int(length))
|
|
||||||
Mock.record("read(\(length))")
|
Mock.record("read(\(length))")
|
||||||
return Int32(length)
|
let count = min(Int32(length), Mock.fileReadLimit ?? Int32(length))
|
||||||
|
if count > 0 { memset(buffer, 0xAB, Int(count)) }
|
||||||
|
return count
|
||||||
}
|
}
|
||||||
fileAPI.pointee.write = { _, _, length in
|
fileAPI.pointee.write = { _, _, length in
|
||||||
Mock.record("write(\(length))")
|
Mock.record("write(\(length))")
|
||||||
|
|||||||
@@ -345,6 +345,19 @@ struct WrapperTests {
|
|||||||
#expect(Mock.eventCount("close") == 1)
|
#expect(Mock.eventCount("close") == 1)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Test func fileHandleReadLengthReturnsOnlyTheBytesRead() throws {
|
||||||
|
let handle = try File.Handle(path: "save.dat", mode: [.read, .readData])
|
||||||
|
|
||||||
|
Mock.fileReadLimit = 3
|
||||||
|
#expect(try handle.read(length: 8) == [0xAB, 0xAB, 0xAB])
|
||||||
|
|
||||||
|
Mock.fileReadLimit = 0
|
||||||
|
#expect(try handle.read(length: 8).isEmpty)
|
||||||
|
|
||||||
|
Mock.fileReadLimit = -1
|
||||||
|
#expect(throws: PlaydateError.self) { try handle.read(length: 8) }
|
||||||
|
}
|
||||||
|
|
||||||
// MARK: JSON
|
// MARK: JSON
|
||||||
|
|
||||||
@Test func jsonDecodeBuildsTheValueTree() throws {
|
@Test func jsonDecodeBuildsTheValueTree() throws {
|
||||||
|
|||||||
Reference in New Issue
Block a user