Skip to content

Instantly share code, notes, and snippets.

@king1600
Last active March 28, 2018 02:36
Show Gist options
  • Save king1600/9fc4e14a2f24f2c89df01795d4ec9e22 to your computer and use it in GitHub Desktop.
Save king1600/9fc4e14a2f24f2c89df01795d4ec9e22 to your computer and use it in GitHub Desktop.
use @pony_ctx[Ptr]()
use @pony_alloc[Ptr](ctx: Ptr tag, size: USize)
use @pony_realloc[Ptr](ctx: Ptr tag, ptr: Ptr tag, size: USize)
use @memcpy[Ptr](dest: USize, src: USize, bytes: USize)
use @memmove[Ptr](dest: USize, src: USize, bytes: USize)
type Ptr is Pointer[U8]
type Option[T] is (T | None)
interface ByteArray
fun size(): USize
fun cpointer(offset: USize = 0): Ptr tag
class ByteBuffer
"""
Readable, Writable and Resizable array of bytes
"""
var _data: Ptr = Ptr
var _capacity: USize = 0
var _read_pos: USize = 0
var _write_pos: USize = 0
fun size(): USize =>
"""
Get the amount of bytes remaining in the byte buffer
"""
_write_pos - _read_pos
fun read(length: USize): Array[U8] iso^ =>
"""
Read an array buffer from the byte buffer using a given amount of bytes.
"""
let data_ptr = if _data.is_null() then 0 else _data.usize() end
recover
let bytes = length.min(size())
let output = Array[U8](bytes)
if \likely\ (data_ptr isnt 0) and (bytes isnt 0) then
output.undefined[U8](bytes)
@memcpy(output.cpointer().usize(), data_ptr + _read_pos, bytes)
end
consume output
end
fun ref write(data: ByteArray, length: USize = 0) =>
"""
Write a byte pointer array to the buffer (String or Array[U8]).
"""
write_ptr(data.cpointer(), data.size())
fun ref write_ptr(data: Ptr tag, length: USize) =>
"""
Write content from a byte pointer into the current byte buffer.
0 sized pointer data is not processed and buffer is potentially resized.
"""
if \unlikely\ length is 0 then return end
let context = @pony_ctx()
let new_size = _write_pos + length
// initialize the buffer
if \unlikely\ _data.is_null() then
_capacity = length.max(8)
_data = @pony_alloc(context, _capacity)
end
// compact front bytes
if _read_pos isnt 0 then
@memmove(_data.usize(), _data.usize() + _read_pos, size())
_write_pos = _write_pos - (_read_pos = 0)
end
// ensure buffer capacity
if new_size > _capacity then
_capacity = (new_size * 14) / 10
_data = @pony_realloc(context, _data, _capacity)
end
// write contents
@memcpy(_data.usize() + _write_pos, _data.usize(), length)
_write_pos = _write_pos + length
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment