use crate::error::{Jp2Error, Result};
#[inline]
pub fn read_u8(buf: &[u8], offset: usize) -> Result<u8> {
buf.get(offset)
.copied()
.ok_or(Jp2Error::OutOfBounds { offset, len: 1 })
}
#[inline]
pub fn read_u16_be(buf: &[u8], offset: usize) -> Result<u16> {
let b = buf
.get(offset..offset + 2)
.ok_or(Jp2Error::OutOfBounds { offset, len: 2 })?;
Ok(u16::from_be_bytes([b[0], b[1]]))
}
#[inline]
pub fn read_u32_be(buf: &[u8], offset: usize) -> Result<u32> {
let b = buf
.get(offset..offset + 4)
.ok_or(Jp2Error::OutOfBounds { offset, len: 4 })?;
Ok(u32::from_be_bytes([b[0], b[1], b[2], b[3]]))
}
#[inline]
pub fn read_u64_be(buf: &[u8], offset: usize) -> Result<u64> {
let b = buf
.get(offset..offset + 8)
.ok_or(Jp2Error::OutOfBounds { offset, len: 8 })?;
Ok(u64::from_be_bytes([
b[0], b[1], b[2], b[3], b[4], b[5], b[6], b[7],
]))
}
#[inline]
pub fn write_u8(buf: &mut [u8], offset: usize, val: u8) -> Result<()> {
let slot = buf
.get_mut(offset)
.ok_or(Jp2Error::OutOfBounds { offset, len: 1 })?;
*slot = val;
Ok(())
}
#[inline]
pub fn write_u16_be(buf: &mut [u8], offset: usize, val: u16) -> Result<()> {
let b = buf
.get_mut(offset..offset + 2)
.ok_or(Jp2Error::OutOfBounds { offset, len: 2 })?;
let bytes = val.to_be_bytes();
b[0] = bytes[0];
b[1] = bytes[1];
Ok(())
}
#[inline]
pub fn write_u32_be(buf: &mut [u8], offset: usize, val: u32) -> Result<()> {
let b = buf
.get_mut(offset..offset + 4)
.ok_or(Jp2Error::OutOfBounds { offset, len: 4 })?;
let bytes = val.to_be_bytes();
b.copy_from_slice(&bytes);
Ok(())
}
pub struct SliceReader<'a> {
data: &'a [u8],
pos: usize,
}
impl<'a> SliceReader<'a> {
pub fn new(data: &'a [u8]) -> Self {
Self { data, pos: 0 }
}
#[inline]
pub fn tell(&self) -> usize {
self.pos
}
#[inline]
pub fn remaining(&self) -> usize {
self.data.len().saturating_sub(self.pos)
}
pub fn read_u8(&mut self) -> Result<u8> {
let v = read_u8(self.data, self.pos)?;
self.pos += 1;
Ok(v)
}
pub fn read_u16_be(&mut self) -> Result<u16> {
let v = read_u16_be(self.data, self.pos)?;
self.pos += 2;
Ok(v)
}
pub fn read_u32_be(&mut self) -> Result<u32> {
let v = read_u32_be(self.data, self.pos)?;
self.pos += 4;
Ok(v)
}
pub fn read_u64_be(&mut self) -> Result<u64> {
let v = read_u64_be(self.data, self.pos)?;
self.pos += 8;
Ok(v)
}
pub fn read_bytes(&mut self, n: usize) -> Result<&'a [u8]> {
let end = self.pos + n;
let slice = self.data.get(self.pos..end).ok_or(Jp2Error::OutOfBounds {
offset: self.pos,
len: n,
})?;
self.pos = end;
Ok(slice)
}
pub fn skip(&mut self, n: usize) -> Result<()> {
let new_pos = self.pos + n;
if new_pos > self.data.len() {
return Err(Jp2Error::OutOfBounds {
offset: self.pos,
len: n,
});
}
self.pos = new_pos;
Ok(())
}
pub fn seek(&mut self, pos: usize) -> Result<()> {
if pos > self.data.len() {
return Err(Jp2Error::OutOfBounds {
offset: pos,
len: 0,
});
}
self.pos = pos;
Ok(())
}
}
pub struct VecWriter {
data: Vec<u8>,
}
impl VecWriter {
pub fn new() -> Self {
Self { data: Vec::new() }
}
pub fn with_capacity(cap: usize) -> Self {
Self {
data: Vec::with_capacity(cap),
}
}
#[inline]
pub fn tell(&self) -> usize {
self.data.len()
}
pub fn write_u8(&mut self, val: u8) {
self.data.push(val);
}
pub fn write_u16_be(&mut self, val: u16) {
self.data.extend_from_slice(&val.to_be_bytes());
}
pub fn write_u32_be(&mut self, val: u32) {
self.data.extend_from_slice(&val.to_be_bytes());
}
pub fn write_u64_be(&mut self, val: u64) {
self.data.extend_from_slice(&val.to_be_bytes());
}
pub fn write_bytes(&mut self, bytes: &[u8]) {
self.data.extend_from_slice(bytes);
}
pub fn as_slice(&self) -> &[u8] {
&self.data
}
pub fn into_vec(self) -> Vec<u8> {
self.data
}
}
impl Default for VecWriter {
fn default() -> Self {
Self::new()
}
}