// ByteReader:定长字节流上的顺序/随机读取。
//
// ISO 9660 的数值字段大多是「both-endian」(小端 4 字节 + 大端 4 字节各一份),
// 因此这里同时提供单端与双端读取,供上层按结构体字段选择。
///|
pub struct ByteReader {
data : Bytes
mut pos : Int32
}
///|
pub fn ByteReader::new(data : Bytes) -> ByteReader {
{ data, pos: 0, }
}
///|
pub fn ByteReader::position(self : ByteReader) -> Int32 {
self.pos
}
///|
pub fn ByteReader::remaining(self : ByteReader) -> Int32 {
self.data.length() - self.pos
}
///|
pub fn ByteReader::seek(self : ByteReader, pos : Int32) -> Unit raise IsoError {
if pos < 0 || pos > self.data.length() {
raise Truncated
}
self.pos = pos
}
///|
pub fn ByteReader::skip(self : ByteReader, n : Int32) -> Unit raise IsoError {
self.seek(self.pos + n)
}
///|
pub fn ByteReader::read_u8(self : ByteReader) -> UInt32 raise IsoError {
if self.remaining() < 1 {
raise Truncated
}
let v = self.data[self.pos].to_uint()
self.pos += 1
v
}
///|
pub fn ByteReader::read_u16_le(self : ByteReader) -> Int32 raise IsoError {
let a = self.read_u8().reinterpret_as_int()
let b = self.read_u8().reinterpret_as_int()
a | (b << 8)
}
///|
pub fn ByteReader::read_u16_be(self : ByteReader) -> Int32 raise IsoError {
let a = self.read_u8().reinterpret_as_int()
let b = self.read_u8().reinterpret_as_int()
(a << 8) | b
}
///|
pub fn ByteReader::read_u32_le(self : ByteReader) -> Int32 raise IsoError {
let a = self.read_u8().reinterpret_as_int()
let b = self.read_u8().reinterpret_as_int()
let c = self.read_u8().reinterpret_as_int()
let d = self.read_u8().reinterpret_as_int()
a | (b << 8) | (c << 16) | (d << 24)
}
///|
pub fn ByteReader::read_u32_be(self : ByteReader) -> Int32 raise IsoError {
let a = self.read_u8().reinterpret_as_int()
let b = self.read_u8().reinterpret_as_int()
let c = self.read_u8().reinterpret_as_int()
let d = self.read_u8().reinterpret_as_int()
(a << 24) | (b << 16) | (c << 8) | d
}
///|
/// ISO 9660 的 both-endian 4 字节整数:前 4 字节小端,后 4 字节大端。
/// 两份必须一致,否则映像结构不可信。
pub fn ByteReader::read_u32_both(self : ByteReader) -> Int32 raise IsoError {
let le = self.read_u32_le()
let be = self.read_u32_be()
if le != be {
raise BadBothEndian
}
le
}
///|
pub fn ByteReader::read_u16_both(self : ByteReader) -> Int32 raise IsoError {
let le = self.read_u16_le()
let be = self.read_u16_be()
if le != be {
raise BadBothEndian
}
le
}
///|
pub fn ByteReader::read_bytes(
self : ByteReader,
n : Int32,
) -> Bytes raise IsoError {
if n < 0 || self.remaining() < n {
raise Truncated
}
let out = FixedArray::make(n, b'\x00')
for i = 0; i < n; i = i + 1 {
out[i] = self.data[self.pos + i]
}
self.pos += n
Bytes::from_array(out[:])
}
///|
/// 读取定长 ASCII 字段:遇 NUL 截断,尾部空格忽略。
pub fn ByteReader::read_ascii(
self : ByteReader,
n : Int32,
) -> String raise IsoError {
let raw = self.read_bytes(n)
let mut out = ""
for i = 0; i < n; i = i + 1 {
let b = raw[i].to_uint().reinterpret_as_int()
if b == 0 {
break
}
out = out + Int32::unsafe_to_char(b).to_string()
}
out.trim_end().to_owned()
}