mirror of
https://github.com/bspeice/kaitai_rust
synced 2024-11-24 06:48:09 -05:00
Initial draft for the Kaitai API
This commit is contained in:
commit
bfeb073143
5
.gitignore
vendored
Normal file
5
.gitignore
vendored
Normal file
@ -0,0 +1,5 @@
|
||||
.idea/
|
||||
|
||||
/target
|
||||
**/*.rs.bk
|
||||
Cargo.lock
|
7
Cargo.toml
Normal file
7
Cargo.toml
Normal file
@ -0,0 +1,7 @@
|
||||
[package]
|
||||
name = "kaitai_runtime"
|
||||
version = "0.1.0"
|
||||
authors = ["Bradlee Speice <bradlee@speice.io>"]
|
||||
edition = "2018"
|
||||
|
||||
[dependencies]
|
262
src/lib.rs
Normal file
262
src/lib.rs
Normal file
@ -0,0 +1,262 @@
|
||||
use std::io;
|
||||
use std::io::Read;
|
||||
use std::io::Seek;
|
||||
|
||||
#[derive(Debug)]
|
||||
pub enum KaitaiError<'a> {
|
||||
InvalidContents { actual: &'a [u8] },
|
||||
InvalidKey,
|
||||
IoError(io::Error),
|
||||
}
|
||||
|
||||
impl<'a> From<io::Error> for KaitaiError<'a> {
|
||||
fn from(e: io::Error) -> Self {
|
||||
KaitaiError::IoError(e)
|
||||
}
|
||||
}
|
||||
|
||||
type Result<'a, T> = std::result::Result<T, KaitaiError<'a>>;
|
||||
|
||||
pub trait KaitaiStruct<'a>
|
||||
{
|
||||
type Parent: KaitaiStruct<'a>;
|
||||
type Root: KaitaiStruct<'a>;
|
||||
|
||||
fn new<S: KaitaiStream>(stream: &mut S) -> Result<Self>
|
||||
where
|
||||
Self: Sized;
|
||||
|
||||
/*
|
||||
fn read<S: KaitaiStream<'a>>(
|
||||
&mut self,
|
||||
|
||||
)
|
||||
*/
|
||||
}
|
||||
|
||||
pub trait KaitaiStream {
|
||||
fn is_eof(&self) -> io::Result<bool>;
|
||||
fn seek(&mut self, position: u64) -> io::Result<()>;
|
||||
fn pos(&self) -> io::Result<u64>;
|
||||
fn size(&self) -> io::Result<u64>;
|
||||
|
||||
fn read_s1(&mut self) -> io::Result<i8>;
|
||||
fn read_s2be(&mut self) -> io::Result<i16>;
|
||||
fn read_s4be(&mut self) -> io::Result<i32>;
|
||||
fn read_s8be(&mut self) -> io::Result<i64>;
|
||||
fn read_s2le(&mut self) -> io::Result<i16>;
|
||||
fn read_s4le(&mut self) -> io::Result<i32>;
|
||||
fn read_s8le(&mut self) -> io::Result<i64>;
|
||||
|
||||
fn read_u1(&mut self) -> io::Result<u8>;
|
||||
fn read_u2be(&mut self) -> io::Result<u16>;
|
||||
fn read_u4be(&mut self) -> io::Result<u32>;
|
||||
fn read_u8be(&mut self) -> io::Result<u64>;
|
||||
fn read_u2le(&mut self) -> io::Result<u16>;
|
||||
fn read_u4le(&mut self) -> io::Result<u32>;
|
||||
fn read_u8le(&mut self) -> io::Result<u64>;
|
||||
|
||||
fn read_f4be(&mut self) -> io::Result<f32>;
|
||||
fn read_f8be(&mut self) -> io::Result<f64>;
|
||||
fn read_f4le(&mut self) -> io::Result<f32>;
|
||||
fn read_f8le(&mut self) -> io::Result<f64>;
|
||||
|
||||
fn align_to_byte(&mut self) -> io::Result<()>;
|
||||
fn read_bits_int(&mut self, n: u32) -> io::Result<u64>;
|
||||
|
||||
fn read_bytes(&mut self, dst: &mut [u8], len: usize) -> io::Result<&[u8]>;
|
||||
fn read_bytes_full(&mut self) -> io::Result<&[u8]>;
|
||||
fn read_bytes_term(
|
||||
&mut self,
|
||||
term: char,
|
||||
include: bool,
|
||||
consume: bool,
|
||||
eos_error: bool,
|
||||
) -> io::Result<&[u8]>;
|
||||
|
||||
/// Verify a magic sequence occurs in the file. Because the size is known at compile-time
|
||||
/// (and is generally very small), we ask that our caller pass in a buffer for us.
|
||||
fn ensure_fixed_contents(&mut self, expected: &[u8], buf: &mut [u8]) -> Result<&[u8]> {
|
||||
let actual = self.read_bytes(buf, expected.len())?;
|
||||
if actual == expected {
|
||||
Ok(actual)
|
||||
} else {
|
||||
// Return what the actual contents were; our caller provided us
|
||||
// what was expected so we don't need to return it, and it makes
|
||||
// the lifetimes way easier
|
||||
Err(KaitaiError::InvalidContents { actual })
|
||||
}
|
||||
}
|
||||
|
||||
/// Return a byte array that is sized to exclude all trailing instances of the
|
||||
/// padding character. Because this operation is immutable on the underlying byte slice,
|
||||
/// we don't allocate a second buffer.
|
||||
fn bytes_strip_right(bytes: &[u8], pad: u8) -> &[u8] {
|
||||
let mut new_len = bytes.len();
|
||||
while new_len > 0 && bytes[new_len - 1] == pad {
|
||||
new_len -= 1;
|
||||
}
|
||||
&bytes[..new_len]
|
||||
}
|
||||
|
||||
/// Return a byte array that contains all bytes up until the
|
||||
/// termination byte. Can optionally include the termination byte as well.
|
||||
/// Because this operation is immutable on the underlying byte slice,
|
||||
/// we don't allocate a second buffer.
|
||||
fn bytes_terminate(bytes: &[u8], term: u8, include_term: bool) -> &[u8] {
|
||||
let mut new_len = 0;
|
||||
while bytes[new_len] != term && new_len < bytes.len() {
|
||||
new_len += 1;
|
||||
}
|
||||
|
||||
if include_term && new_len < bytes.len() {
|
||||
new_len += 1;
|
||||
}
|
||||
|
||||
&bytes[..new_len]
|
||||
}
|
||||
}
|
||||
|
||||
struct BytesReader<'a> {
|
||||
bytes: &'a[u8],
|
||||
pos: usize,
|
||||
bits: u8,
|
||||
bits_left: u8,
|
||||
}
|
||||
impl<'a> BytesReader<'a> {
|
||||
fn new(bytes: &'a[u8]) -> Self {
|
||||
BytesReader {
|
||||
bytes,
|
||||
pos: 0,
|
||||
bits: 0,
|
||||
bits_left: 0
|
||||
}
|
||||
}
|
||||
}
|
||||
impl<'a> From<&'a[u8]> for BytesReader<'a> {
|
||||
fn from(b: &'a[u8]) -> Self {
|
||||
BytesReader::new(b)
|
||||
}
|
||||
}
|
||||
impl<'a> KaitaiStream for BytesReader<'a> {
|
||||
fn is_eof(&self) -> io::Result<bool> {
|
||||
unimplemented!()
|
||||
}
|
||||
|
||||
fn seek(&mut self, position: u64) -> io::Result<()> {
|
||||
unimplemented!()
|
||||
}
|
||||
|
||||
fn pos(&self) -> io::Result<u64> {
|
||||
unimplemented!()
|
||||
}
|
||||
|
||||
fn size(&self) -> io::Result<u64> {
|
||||
unimplemented!()
|
||||
}
|
||||
|
||||
fn read_s1(&mut self) -> io::Result<i8> {
|
||||
unimplemented!()
|
||||
}
|
||||
|
||||
fn read_s2be(&mut self) -> io::Result<i16> {
|
||||
unimplemented!()
|
||||
}
|
||||
|
||||
fn read_s4be(&mut self) -> io::Result<i32> {
|
||||
unimplemented!()
|
||||
}
|
||||
|
||||
fn read_s8be(&mut self) -> io::Result<i64> {
|
||||
unimplemented!()
|
||||
}
|
||||
|
||||
fn read_s2le(&mut self) -> io::Result<i16> {
|
||||
unimplemented!()
|
||||
}
|
||||
|
||||
fn read_s4le(&mut self) -> io::Result<i32> {
|
||||
unimplemented!()
|
||||
}
|
||||
|
||||
fn read_s8le(&mut self) -> io::Result<i64> {
|
||||
unimplemented!()
|
||||
}
|
||||
|
||||
fn read_u1(&mut self) -> io::Result<u8> {
|
||||
unimplemented!()
|
||||
}
|
||||
|
||||
fn read_u2be(&mut self) -> io::Result<u16> {
|
||||
unimplemented!()
|
||||
}
|
||||
|
||||
fn read_u4be(&mut self) -> io::Result<u32> {
|
||||
unimplemented!()
|
||||
}
|
||||
|
||||
fn read_u8be(&mut self) -> io::Result<u64> {
|
||||
unimplemented!()
|
||||
}
|
||||
|
||||
fn read_u2le(&mut self) -> io::Result<u16> {
|
||||
unimplemented!()
|
||||
}
|
||||
|
||||
fn read_u4le(&mut self) -> io::Result<u32> {
|
||||
unimplemented!()
|
||||
}
|
||||
|
||||
fn read_u8le(&mut self) -> io::Result<u64> {
|
||||
unimplemented!()
|
||||
}
|
||||
|
||||
fn read_f4be(&mut self) -> io::Result<f32> {
|
||||
unimplemented!()
|
||||
}
|
||||
|
||||
fn read_f8be(&mut self) -> io::Result<f64> {
|
||||
unimplemented!()
|
||||
}
|
||||
|
||||
fn read_f4le(&mut self) -> io::Result<f32> {
|
||||
unimplemented!()
|
||||
}
|
||||
|
||||
fn read_f8le(&mut self) -> io::Result<f64> {
|
||||
unimplemented!()
|
||||
}
|
||||
|
||||
fn align_to_byte(&mut self) -> io::Result<()> {
|
||||
unimplemented!()
|
||||
}
|
||||
|
||||
fn read_bits_int(&mut self, n: u32) -> io::Result<u64> {
|
||||
unimplemented!()
|
||||
}
|
||||
|
||||
fn read_bytes(&mut self, buf: &mut [u8], len: usize) -> io::Result<&[u8]> {
|
||||
unimplemented!()
|
||||
}
|
||||
|
||||
fn read_bytes_full(&mut self) -> io::Result<&[u8]> {
|
||||
unimplemented!()
|
||||
}
|
||||
|
||||
fn read_bytes_term(&mut self, term: char, include: bool, consume: bool, eos_error: bool) -> io::Result<&[u8]> {
|
||||
unimplemented!()
|
||||
}
|
||||
}
|
||||
|
||||
#[cfg(test)]
|
||||
mod tests {
|
||||
use super::*;
|
||||
|
||||
#[test]
|
||||
fn basic_strip_right() {
|
||||
let b = [1, 2, 3, 4, 5, 5, 5, 5];
|
||||
let c = BytesReader::bytes_strip_right(&b, 5);
|
||||
|
||||
assert_eq!([1, 2, 3, 4], c);
|
||||
}
|
||||
}
|
Loading…
Reference in New Issue
Block a user