I am trying to use a CircularBuffer<UInt8> from SwiftNIO to store data and once the buffer is almost full dump the contents to a file using an OutputStream. Unfortunately, the OutputStream.write() method takes UnsafePointer as an argument, while the CircularBuffer can output UnsafeBufferPointer . Is there a way to convert CircularBuffer to UnsafePointer?
I have tried to extend CircularBuffer with the following code that I am using with success to convert structs to Byte arrays as it was suggested that CircularBuffer is in fact a struct, but I am getting garbage in my output file:
extension CircularBuffer {
func toBytes() -> [UInt8] {
let capacity = MemoryLayout<Self>.size
var mutableValue = self
return withUnsafePointer(to: &mutableValue) {
return $0.withMemoryRebound(to: UInt8.self, capacity: capacity) {
return Array(UnsafeBufferPointer(start: $0, count: capacity))
}
}
}
}
Any thoughts?
CircularBufferis a struct with an internalContiguousArrayfor the element storage.ContiguousArrayis also a struct, with internal pointers to the actual element storage.Your current code produce garbage because it returns the memory representation of the
struct CircularBufferitself, and not the bytes of the elements which it represents.As a collection,
CircularBufferhas awithContiguousStorageIfAvailable()method which calls a closure with a pointer to the element storage if such contiguous storage exists. The closure is called with anUnsafeBufferPointerargument from which you can obtain thebaseAddress:But there is a problem:
CircularBufferjust inherits the default implementation fromSequencewhich returnsnilwithout calling the closure. This is a known issue. So the above code would compile, but not work.A simple way (at the cost of copying the contents) would be to use that you can initialize an array from a collection: