should there be an easier way to load misaligned values from raw buffers? Right now I have this for loading arbitrary big endian FixedWidthInteger
s from an ArraySlice
func load<T, U>(bigEndian:T.Type, as type:U.Type, from slice:ArraySlice<UInt8>) -> U
where T:FixedWidthInteger, U:BinaryInteger
{
return slice.withUnsafeBufferPointer
{
(buffer:UnsafeBufferPointer<UInt8>) in
var storage:T = .init()
let value:T = withUnsafeMutablePointer(to: &storage)
{
$0.deinitialize(count: 1)
guard buffer.count >= MemoryLayout<T>.size,
let source:UnsafeRawPointer = buffer.baseAddress.map(UnsafeRawPointer.init(_:))
else
{
fatalError("attempt to load \(T.self) from buffer of size \(buffer.count)")
}
let raw:UnsafeMutableRawPointer = .init($0)
raw.copyMemory(from: source, byteCount: MemoryLayout<T>.size)
return raw.load(as: T.self)
}
return U(T(bigEndian: value))
}
}
this is really hard to get right (did you remember to deinitialize storage
?) and it’s really easy to accidentally make a memory-unsafe implementation that works for standard library integer types but not the generic family