Last active
March 28, 2018 02:36
-
-
Save king1600/9fc4e14a2f24f2c89df01795d4ec9e22 to your computer and use it in GitHub Desktop.
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
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