ignis 0.1.0

A library for editing various 3DSFE formats.
Documentation
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)
    }
}