///|
/// A strict forward-only cursor over immutable bytes.
priv struct ByteCursor {
data : Bytes
base_offset : Int
mut position : Int
}
///|
fn ByteCursor::new(data : Bytes) -> ByteCursor {
{ data, base_offset: 0, position: 0 }
}
///|
fn ByteCursor::with_base(data : Bytes, base_offset : Int) -> ByteCursor {
{ data, base_offset, position: 0 }
}
///|
fn ByteCursor::offset(self : ByteCursor) -> Int {
self.base_offset + self.position
}
///|
fn ByteCursor::remaining(self : ByteCursor) -> Int {
self.data.length() - self.position
}
///|
fn ByteCursor::read_byte(self : ByteCursor) -> Byte raise VcdiffError {
if self.position >= self.data.length() {
raise TruncatedInput(offset=self.position, needed=1, available=0)
}
let value = self.data[self.position]
self.position += 1
value
}
///|
fn ByteCursor::read_exact(
self : ByteCursor,
count : Int,
) -> Bytes raise VcdiffError {
if count < 0 {
raise InvalidOption(option="count", reason="must not be negative")
}
let available = self.remaining()
if count > available {
raise TruncatedInput(offset=self.position, needed=count, available~)
}
let start = self.position
self.position += count
self.data[start:self.position].to_owned()
}
///|
fn ByteCursor::read_subcursor(
self : ByteCursor,
count : Int,
) -> ByteCursor raise VcdiffError {
let start = self.offset()
let data = self.read_exact(count)
ByteCursor::with_base(data, start)
}