class val BitsU8 is Codec[U8]
"""
Read or write an unsigned integer of a specified bit width (1–8 bits),
returning a `U8`.
"""
let _count: U8
new val create(count: U8) =>
_count = count
fun decode(data: Array[U8] val, offset: USize)
: ((U8, USize) | DecodeError)
=>
let cursor = _BitCursor(data, offset / 8, (offset % 8).u8())
if cursor.available_bits() < _count.usize() then
return InsufficientData
end
try
(cursor.read_bits(_count)?.u8(), _count.usize())
else
MalformedData("Failed to read " + _count.string() + " bits", offset)
end
fun _encode_bits(value: U8, writer: _BitWriter ref)
: (_BitWriter ref | EncodeError)
=>
if (_count < 8) and ((value >> _count) > 0) then
return EncodeViolation(
value.string() + " exceeds " + _count.string() + " bits")
end
writer.write_bits(value.u64(), _count)
writer
class val BitsU16 is Codec[U16]
"""
Read or write an unsigned integer of a specified bit width (1–16 bits),
returning a `U16`. Bits are read big-endian.
"""
let _count: U8
new val create(count: U8) =>
_count = count
fun decode(data: Array[U8] val, offset: USize)
: ((U16, USize) | DecodeError)
=>
let cursor = _BitCursor(data, offset / 8, (offset % 8).u8())
if cursor.available_bits() < _count.usize() then
return InsufficientData
end
try
(cursor.read_bits(_count)?.u16(), _count.usize())
else
MalformedData("Failed to read " + _count.string() + " bits", offset)
end
fun _encode_bits(value: U16, writer: _BitWriter ref)
: (_BitWriter ref | EncodeError)
=>
if (_count < 16) and ((value >> _count.u16()) > 0) then
return EncodeViolation(
value.string() + " exceeds " + _count.string() + " bits")
end
writer.write_bits(value.u64(), _count)
writer
class val BitsU32 is Codec[U32]
"""
Read or write an unsigned integer of a specified bit width (1–32 bits),
returning a `U32`. Bits are read big-endian.
"""
let _count: U8
new val create(count: U8) =>
_count = count
fun decode(data: Array[U8] val, offset: USize)
: ((U32, USize) | DecodeError)
=>
let cursor = _BitCursor(data, offset / 8, (offset % 8).u8())
if cursor.available_bits() < _count.usize() then
return InsufficientData
end
try
(cursor.read_bits(_count)?.u32(), _count.usize())
else
MalformedData("Failed to read " + _count.string() + " bits", offset)
end
fun _encode_bits(value: U32, writer: _BitWriter ref)
: (_BitWriter ref | EncodeError)
=>
if (_count < 32) and ((value >> _count.u32()) > 0) then
return EncodeViolation(
value.string() + " exceeds " + _count.string() + " bits")
end
writer.write_bits(value.u64(), _count)
writer
class val BitsU64 is Codec[U64]
"""
Read or write an unsigned integer of a specified bit width (1–64 bits),
returning a `U64`. Bits are read big-endian.
"""
let _count: U8
new val create(count: U8) =>
_count = count
fun decode(data: Array[U8] val, offset: USize)
: ((U64, USize) | DecodeError)
=>
let cursor = _BitCursor(data, offset / 8, (offset % 8).u8())
if cursor.available_bits() < _count.usize() then
return InsufficientData
end
try
(cursor.read_bits(_count)?, _count.usize())
else
MalformedData("Failed to read " + _count.string() + " bits", offset)
end
fun _encode_bits(value: U64, writer: _BitWriter ref)
: (_BitWriter ref | EncodeError)
=>
if (_count < 64) and ((value >> _count.u64()) > 0) then
return EncodeViolation(
value.string() + " exceeds " + _count.string() + " bits")
end
writer.write_bits(value, _count)
writer