You can not select more than 25 topics
Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
174 lines
9.4 KiB
174 lines
9.4 KiB
class_name StreamBuffer |
|
extends RefCounted |
|
|
|
var buffer : PackedByteArray |
|
var capacity : int |
|
var size : int |
|
var cursor : int |
|
## Bit index (0 to 7) for writing / reading the next bit. |
|
var bit : int |
|
|
|
func _init(buf: PackedByteArray) -> void: |
|
buffer = buf |
|
capacity = buf.size() |
|
|
|
## Creates a new StreamBuffer with the specified capacity. |
|
## This is intended for writing / encoding data. |
|
static func with_capacity(initial_capacity: int) -> StreamBuffer: |
|
var buf := PackedByteArray() |
|
buf.resize(initial_capacity) |
|
return new(buf) |
|
|
|
## Creates a new StreamBuffer from the specified buffer, pre-initializing "size". |
|
## This is intended for reading / decoding data. |
|
static func from_bytes(buf: PackedByteArray) -> StreamBuffer: |
|
var stream := new(buf) |
|
stream.size = stream.capacity |
|
return stream |
|
|
|
|
|
## Returns the remaining capacity before the buffer needs to be resized to fit more data. |
|
func remaining_capacity() -> int: |
|
return capacity - size |
|
|
|
## Returns the remaining number of bytes to read. |
|
func remaining_bytes() -> int: |
|
return size - cursor |
|
|
|
|
|
## Returns a slice of this StreamBuffer. |
|
## By default returns a slice of the currently written bytes. |
|
func slice(begin: int = 0, end: int = -1) -> PackedByteArray: |
|
if end < 0: end = size |
|
return buffer.slice(begin, end) |
|
|
|
## Clears the buffer and resets the cursor, ready to encode new data. |
|
## For performance, does not clear the existing data in the underlying buffer. |
|
func clear() -> void: |
|
size = 0 |
|
cursor = 0 |
|
bit = 0 |
|
|
|
## Ensures that the capacity for this buffer is large enough for the specified number of bytes to be written. |
|
## For the sake of not resizing too often, this simply doubles the current capacity. |
|
func ensure_capacity(required_bytes: int) -> void: |
|
var total_required_capacity := size + required_bytes |
|
if capacity < total_required_capacity: |
|
while capacity < total_required_capacity: capacity *= 2 |
|
buffer.resize(capacity) |
|
|
|
|
|
func write_int8 (value: int) -> void: ensure_capacity(1); buffer.encode_s8 (size, value); size += 1; bit = 0 |
|
func write_int16(value: int) -> void: ensure_capacity(2); buffer.encode_s16(size, value); size += 2; bit = 0 |
|
func write_int32(value: int) -> void: ensure_capacity(4); buffer.encode_s32(size, value); size += 4; bit = 0 |
|
func write_int64(value: int) -> void: ensure_capacity(8); buffer.encode_s64(size, value); size += 8; bit = 0 |
|
|
|
func write_byte (value: int) -> void: write_uint8(value) |
|
func write_uint8 (value: int) -> void: ensure_capacity(1); buffer.encode_u8 (size, value); size += 1; bit = 0 |
|
func write_uint16(value: int) -> void: ensure_capacity(2); buffer.encode_u16(size, value); size += 2; bit = 0 |
|
func write_uint32(value: int) -> void: ensure_capacity(4); buffer.encode_u32(size, value); size += 4; bit = 0 |
|
func write_uint64(value: int) -> void: ensure_capacity(8); buffer.encode_u64(size, value); size += 8; bit = 0 |
|
|
|
func write_float16(value: float) -> void: ensure_capacity(2); buffer.encode_half (size, value); size += 2; bit = 0 |
|
func write_float32(value: float) -> void: ensure_capacity(4); buffer.encode_float (size, value); size += 4; bit = 0 |
|
func write_float64(value: float) -> void: ensure_capacity(8); buffer.encode_double(size, value); size += 8; bit = 0 |
|
|
|
func write_vector2_16(value: Vector2) -> void: write_float16(value.x); write_float16(value.y) |
|
func write_vector2_32(value: Vector2) -> void: write_float32(value.x); write_float32(value.y) |
|
func write_vector3_16(value: Vector3) -> void: write_float16(value.x); write_float16(value.y); write_float16(value.z) |
|
func write_vector3_32(value: Vector3) -> void: write_float32(value.x); write_float32(value.y); write_float32(value.z) |
|
|
|
func write_vector2i_16(value: Vector2i) -> void: write_int16(value.x); write_int16(value.y) |
|
func write_vector2i_32(value: Vector2i) -> void: write_int32(value.x); write_int32(value.y) |
|
func write_vector3i_16(value: Vector3i) -> void: write_int16(value.x); write_int16(value.y); write_int16(value.z) |
|
func write_vector3i_32(value: Vector3i) -> void: write_int32(value.x); write_int32(value.y); write_int32(value.z) |
|
|
|
func write_transform2d_16(value: Transform2D) -> void: write_float16(value.get_rotation()); write_vector2_16(value.get_scale()); write_float16(value.get_skew()); write_vector2_16(value.origin); |
|
func write_transform2d_32(value: Transform2D) -> void: write_float32(value.get_rotation()); write_vector2_32(value.get_scale()); write_float32(value.get_skew()); write_vector2_32(value.origin); |
|
func write_transform3d_16(value: Transform3D) -> void: write_vector3_16(value.basis.x); write_vector3_16(value.basis.y); write_vector3_16(value.basis.z); write_vector3_16(value.origin) |
|
func write_transform3d_32(value: Transform3D) -> void: write_vector3_32(value.basis.x); write_vector3_32(value.basis.y); write_vector3_32(value.basis.z); write_vector3_32(value.origin) |
|
|
|
func write_range8 (value: float) -> void: write_uint8 (roundi(value * 255)) |
|
func write_range16(value: float) -> void: write_uint16(roundi(value * 65535)) |
|
func write_range32(value: float) -> void: write_uint32(roundi(value * 4294967295)) |
|
|
|
|
|
func read_int8 () -> int: assert(remaining_bytes() >= 1); var result := buffer.decode_s8 (cursor); cursor += 1; bit = 0; return result |
|
func read_int16() -> int: assert(remaining_bytes() >= 2); var result := buffer.decode_s16(cursor); cursor += 2; bit = 0; return result |
|
func read_int32() -> int: assert(remaining_bytes() >= 4); var result := buffer.decode_s32(cursor); cursor += 4; bit = 0; return result |
|
func read_int64() -> int: assert(remaining_bytes() >= 8); var result := buffer.decode_s64(cursor); cursor += 8; bit = 0; return result |
|
|
|
func read_byte () -> int: return read_uint8() |
|
func read_uint8 () -> int: assert(remaining_bytes() >= 1); var result := buffer.decode_u8 (cursor); cursor += 1; bit = 0; return result |
|
func read_uint16() -> int: assert(remaining_bytes() >= 2); var result := buffer.decode_u16(cursor); cursor += 2; bit = 0; return result |
|
func read_uint32() -> int: assert(remaining_bytes() >= 4); var result := buffer.decode_u32(cursor); cursor += 4; bit = 0; return result |
|
func read_uint64() -> int: assert(remaining_bytes() >= 8); var result := buffer.decode_u64(cursor); cursor += 8; bit = 0; return result |
|
|
|
func read_float16() -> float: assert(remaining_bytes() >= 2); var result := buffer.decode_half (cursor); cursor += 2; bit = 0; return result |
|
func read_float32() -> float: assert(remaining_bytes() >= 4); var result := buffer.decode_float (cursor); cursor += 4; bit = 0; return result |
|
func read_float64() -> float: assert(remaining_bytes() >= 8); var result := buffer.decode_double(cursor); cursor += 8; bit = 0; return result |
|
|
|
func read_vector2_16() -> Vector2: return Vector2(read_float16(), read_float16()) |
|
func read_vector2_32() -> Vector2: return Vector2(read_float32(), read_float32()) |
|
func read_vector3_16() -> Vector3: return Vector3(read_float16(), read_float16(), read_float16()) |
|
func read_vector3_32() -> Vector3: return Vector3(read_float32(), read_float32(), read_float32()) |
|
|
|
func read_vector2i_16() -> Vector2i: return Vector2i(read_int16(), read_int16()) |
|
func read_vector2i_32() -> Vector2i: return Vector2i(read_int32(), read_int32()) |
|
func read_vector3i_16() -> Vector3i: return Vector3i(read_int16(), read_int16(), read_int16()) |
|
func read_vector3i_32() -> Vector3i: return Vector3i(read_int32(), read_int32(), read_int32()) |
|
|
|
func read_transform2d_16() -> Transform2D: return Transform2D(read_float16(), read_vector2_16(), read_float16(), read_vector2_16()) |
|
func read_transform2d_32() -> Transform2D: return Transform2D(read_float32(), read_vector2_32(), read_float32(), read_vector2_32()) |
|
func read_transform3d_16() -> Transform3D: return Transform3D(Basis(read_vector3_16(), read_vector3_16(), read_vector3_16()), read_vector3_16()) |
|
func read_transform3d_32() -> Transform3D: return Transform3D(Basis(read_vector3_32(), read_vector3_32(), read_vector3_32()), read_vector3_32()) |
|
|
|
func read_range8() -> float: return float(read_uint8()) / 255 |
|
func read_range16() -> float: return float(read_uint16()) / 65535 |
|
func read_range32() -> float: return float(read_uint32()) / 4294967295 |
|
|
|
|
|
func write_bit(value: bool) -> void: |
|
if bit == 0: ensure_capacity(1); buffer[size] = 0; size += 1 |
|
buffer[size - 1] = buffer[size - 1] | (int(value) << bit) |
|
bit = (bit + 1) % 8 |
|
func read_bit() -> bool: |
|
if bit == 0: assert(remaining_bytes() >= 1); cursor += 1 |
|
var result := bool((buffer[cursor - 1] >> bit) & 1) |
|
bit = (bit + 1) % 8 |
|
return result |
|
|
|
func write_raw_buffer(value: PackedByteArray) -> void: |
|
ensure_capacity(value.size()) |
|
for i in value.size(): |
|
buffer[size] = value[i] |
|
size += 1 |
|
func read_raw_buffer_into(value: PackedByteArray) -> void: |
|
var length := value.size() |
|
assert(remaining_bytes() >= length) |
|
for i in length: value[i] = buffer[cursor]; cursor += 1 |
|
func read_raw_buffer(length: int) -> PackedByteArray: |
|
var result := PackedByteArray() |
|
result.resize(length) |
|
read_raw_buffer_into(result) |
|
return result |
|
|
|
func write_compressed(value: PackedByteArray, mode: FileAccess.CompressionMode) -> void: |
|
var bytes := value.compress(mode) |
|
write_uint32(value.size()) |
|
write_uint32(bytes.size()) |
|
write_raw_buffer(bytes) |
|
func read_compressed(mode: FileAccess.CompressionMode) -> PackedByteArray: |
|
var uncompressed_length := read_uint32() |
|
var compressed_length := read_uint32() |
|
var bytes := read_raw_buffer(compressed_length) |
|
return bytes.decompress(uncompressed_length, mode) |
|
|
|
func write_string(value: String) -> void: |
|
var bytes := value.to_utf8_buffer() |
|
write_uint16(bytes.size()) |
|
write_raw_buffer(bytes) |
|
func read_string() -> String: |
|
var length := read_uint16() |
|
var bytes := read_raw_buffer(length) |
|
return bytes.get_string_from_utf8()
|
|
|