use super::BinArchive;
use anyhow::{anyhow, Result};
use encoding_rs::{UTF_16LE, SHIFT_JIS};
pub struct BinArchiveReader<'a> {
archive: &'a BinArchive,
position: usize
}
impl<'a> BinArchiveReader<'a> {
pub fn new(archive: &'a BinArchive, position: usize) -> Self {
BinArchiveReader {
archive,
position
}
}
pub fn seek(&mut self, position: usize) {
self.position = position;
}
pub fn skip(&mut self, amount: usize) {
self.position += amount;
}
pub fn tell(&self) -> usize {
return self.position;
}
pub fn read_u8(&mut self) -> Result<u8> {
let value = self.archive.read_u8(self.position)?;
self.position += 1;
Ok(value)
}
pub fn read_u16(&mut self) -> Result<u16> {
let value = self.archive.read_u16(self.position)?;
self.position += 2;
Ok(value)
}
pub fn read_u32(&mut self) -> Result<u32> {
let value = self.archive.read_u32(self.position)?;
self.position += 4;
Ok(value)
}
pub fn read_i8(&mut self) -> Result<i8> {
let value = self.read_u8()?;
Ok(value as i8)
}
pub fn read_i16(&mut self) -> Result<i16> {
let value = self.read_u16()?;
Ok(value as i16)
}
pub fn read_i32(&mut self) -> Result<i32> {
let value = self.read_u32()?;
Ok(value as i32)
}
pub fn read_bytes(&mut self, count: usize) -> Result<Vec<u8>> {
let mut result: Vec<u8> = Vec::new();
for _ in 0..count {
result.push(self.read_u8()?);
}
Ok(result)
}
pub fn read_f32(&mut self) -> Result<f32> {
let value = self.archive.read_f32(self.position)?;
self.position += 4;
Ok(value)
}
pub fn read_string(&mut self) -> Result<Option<String>> {
let value = self.archive.read_string(self.position)?;
self.position += 4;
Ok(value)
}
pub fn read_utf16_string(&mut self) -> Result<String> {
let mut buffer: Vec<u8> = Vec::new();
let mut next_byte_1 = self.read_u8()?;
let mut next_byte_2 = self.read_u8()?;
while next_byte_1 != 0 || next_byte_2 != 0 {
buffer.push(next_byte_1);
buffer.push(next_byte_2);
next_byte_1 = self.read_u8()?;
next_byte_2 = self.read_u8()?;
}
while self.position % 4 != 0 {
self.position += 1;
}
let (result, _enc, errors) = UTF_16LE.decode(buffer.as_slice());
return if errors {
Err(anyhow!("Unable to decode UTF-16 string"))
} else {
Ok(result.into())
}
}
pub fn read_shift_jis_string(&mut self) -> Result<String> {
let mut buffer: Vec<u8> = Vec::new();
let mut next_byte = self.read_u8()?;
while next_byte != 0 {
buffer.push(next_byte);
next_byte = self.read_u8()?;
}
while self.position % 4 != 0 {
self.position += 1;
}
let (result, _enc, errors) = SHIFT_JIS.decode(buffer.as_slice());
return if errors {
Err(anyhow!("Unable to decode SHIFT_JIS string"))
} else {
Ok(result.into())
}
}
pub fn read_label(&mut self, index: usize) -> Result<Option<String>> {
Ok(self.archive.read_label(self.position, index)?)
}
pub fn read_pointer(&mut self) -> Result<Option<usize>> {
let value = self.archive.read_pointer(self.position)?;
self.position += 4;
Ok(value)
}
}