Files
playdate-kit/Sources/PlaydateKit/Support.swift
T

45 lines
1.7 KiB
Swift

internal import CPlaydate
/// Internal C-string helpers shared by the wrappers.
///
/// Passing strings to C goes through the standard `withCString`, which hands
/// out a pointer to the string's own null-terminated storage without copying.
extension String {
/// Creates a string from a nullable C string, or `nil` if the pointer is null.
init?(playdateCString pointer: UnsafePointer<CChar>?) {
guard let pointer else { return nil }
self.init(cString: pointer)
}
/// Copies the string into a newly allocated null-terminated C string.
/// The caller owns the memory and must free it with `deallocate()`.
func copiedPlaydateCString() -> UnsafeMutablePointer<CChar> {
withCString { cString in
let count = utf8.count + 1
let buffer = UnsafeMutablePointer<CChar>.allocate(capacity: count)
buffer.initialize(from: cString, count: count)
return buffer
}
}
}
#if hasFeature(Embedded) && !os(macOS)
/// The Embedded Swift runtime allocates through `posix_memalign(3)`, which
/// the Playdate device C library does not provide. Memory comes from
/// `malloc`, which the SDK's setup code routes to the firmware allocator.
/// The pointer is later released with plain `free`, so it cannot be offset
/// to adjust alignment; the firmware allocator's natural alignment has to
/// satisfy the request, which the precondition asserts.
@c(posix_memalign)
public func posix_memalign(
_ memptr: UnsafeMutablePointer<UnsafeMutableRawPointer?>,
_ alignment: Int,
_ size: Int
) -> CInt {
guard let allocation = malloc(size) else { fatalError() }
precondition(Int(bitPattern: allocation) % alignment == 0)
memptr.pointee = allocation
return 0
}
#endif