105 lines
3.0 KiB
Swift
105 lines
3.0 KiB
Swift
// Copyright © 2023 Rangeproof Pty Ltd. All rights reserved.
|
|
|
|
import Foundation
|
|
|
|
// MARK: - String
|
|
|
|
public extension String {
|
|
var cArray: [CChar] { [UInt8](self.utf8).map { CChar(bitPattern: $0) } }
|
|
|
|
/// Initialize with an optional pointer and a specific length
|
|
init?(pointer: UnsafeRawPointer?, length: Int, encoding: String.Encoding = .utf8) {
|
|
guard
|
|
let pointer: UnsafeRawPointer = pointer,
|
|
let result: String = String(data: Data(bytes: pointer, count: length), encoding: encoding)
|
|
else { return nil }
|
|
|
|
self = result
|
|
}
|
|
|
|
init?<T>(
|
|
libSessionVal: T,
|
|
nullTerminated: Bool = true,
|
|
nullIfEmpty: Bool = false
|
|
) {
|
|
let result: String = {
|
|
guard !nullTerminated else {
|
|
return String(cString: withUnsafeBytes(of: libSessionVal) { [UInt8]($0) })
|
|
}
|
|
|
|
return String(
|
|
data: Data(libSessionVal: libSessionVal, count: MemoryLayout<T>.size),
|
|
encoding: .utf8
|
|
)
|
|
.defaulting(to: "")
|
|
}()
|
|
|
|
guard !nullIfEmpty || !result.isEmpty else { return nil }
|
|
|
|
self = result
|
|
}
|
|
|
|
func toLibSession<T>() -> T {
|
|
let targetSize: Int = MemoryLayout<T>.stride
|
|
let result: UnsafeMutableRawPointer = UnsafeMutableRawPointer.allocate(
|
|
byteCount: targetSize,
|
|
alignment: MemoryLayout<T>.alignment
|
|
)
|
|
self.utf8CString.withUnsafeBytes { result.copyMemory(from: $0.baseAddress!, byteCount: $0.count) }
|
|
|
|
return result.withMemoryRebound(to: T.self, capacity: targetSize) { $0.pointee }
|
|
}
|
|
}
|
|
|
|
public extension Optional<String> {
|
|
func toLibSession<T>() -> T {
|
|
switch self {
|
|
case .some(let value): return value.toLibSession()
|
|
case .none: return "".toLibSession()
|
|
}
|
|
}
|
|
}
|
|
|
|
// MARK: - Data
|
|
|
|
public extension Data {
|
|
var cArray: [UInt8] { [UInt8](self) }
|
|
|
|
init<T>(libSessionVal: T, count: Int) {
|
|
self = Data(
|
|
bytes: Swift.withUnsafeBytes(of: libSessionVal) { [UInt8]($0) },
|
|
count: count
|
|
)
|
|
}
|
|
|
|
func toLibSession<T>() -> T {
|
|
let targetSize: Int = MemoryLayout<T>.stride
|
|
let result: UnsafeMutableRawPointer = UnsafeMutableRawPointer.allocate(
|
|
byteCount: targetSize,
|
|
alignment: MemoryLayout<T>.alignment
|
|
)
|
|
self.withUnsafeBytes { result.copyMemory(from: $0.baseAddress!, byteCount: $0.count) }
|
|
|
|
return result.withMemoryRebound(to: T.self, capacity: targetSize) { $0.pointee }
|
|
}
|
|
}
|
|
|
|
public extension Optional<Data> {
|
|
func toLibSession<T>() -> T {
|
|
switch self {
|
|
case .some(let value): return value.toLibSession()
|
|
case .none: return Data().toLibSession()
|
|
}
|
|
}
|
|
}
|
|
|
|
// MARK: - Array
|
|
|
|
public extension Array where Element == CChar {
|
|
func nullTerminated() -> [Element] {
|
|
guard self.last != CChar(0) else { return self }
|
|
|
|
return self.appending(CChar(0))
|
|
}
|
|
}
|