Expand description
A library for decoding (“chiselling”) structures out of a byte-stream.
This crate primarily provides the Chisel type,
an abstraction for reading values of primitive type.
§Usage
First, create a Chisel, e.g. from an array of bytes:
use byte_chisel::prelude::*;
let bytes = [ 239, 190, 173, 222 ];
let mut chisel = Chisel::from_array(&bytes);You can then read a u32 from the array via:
let value = chisel.u32(Endianness::Little)?;
assert_eq!(value, 0xDEADBEEF);If you provide more data, you can read multiple values:
let bytes = [ 239, 190, 173, 222, 103, 10 ];
let mut chisel = Chisel::from_array(&bytes);
let val1 = chisel.u32(Endianness::Little)?;
let val2 = chisel.u16(Endianness::Little)?;
assert_eq!(val1, 0xDEADBEEF);
assert_eq!(val2, 0x0A67);Most formats use a consistent endianness. You can use a wrapper to avoid repeating it:
let mut chisel_be = chisel.big_endian();
// both of these `u16` are read as big-endian
let hi = chisel_be.u16()?;
let lo = chisel_be.u16()?;§Errors
This crate distinguishes between three types of errors during chiselling: Format Errors, Source Errors and EndOfInput. The byte offset an error occurred at is included for ease of debugging.
See the documentation on ChiselError for details.
§“Breaking”
In most cases, when a chiselling operation returns an error, the Chisel is said to “break”.
(This is called out in the documentation with the phrase “the chisel breaks” and a link to this section.)
A “broken” Chisel no longer accurately tracks the underlying byte-stream:
- Some bytes that are present in the byte-stream are “lost” and inaccessible.
- The tracked byte offset no longer reflects the position in the byte-stream.
Continuing to use a “broken” Chisel is discouraged.
Note that idiomatic use of the ? operator prevents broken Chisel usage.
§API Considerations
For composability, it is recommended that chiselling functions take the input Chisel by mutable reference:
fn chisel_resource_header<S : ChiselSource>(
chisel: &mut Chisel<S>
) -> ChiselResult<ResourceHeader, HeaderError, S> {
todo!()
}This allows using such functions as part of larger decodings:
let count = chisel.u16(Endianness::Little).forward()?;
let mut headers = Vec::with_capacity(count as usize);
for _ in 0..count {
let header = chisel_resource_header(&mut chisel)
.map_err(|e| e.map(FileError::BadHeader))?
;
headers.push(header)
}
/* parse the rest of the file... */§Examples
Decode (“chisel”) a simple resource header consisting of
- a little-endian 32-bit integer id
- a 1-byte tag and
- a null-terminated name
use byte_chisel::prelude::*;
fn chisel_resource_header<S : ChiselSource>(
chisel: &mut Chisel<S>
) -> ChiselResult<ResourceHeader, HeaderError, S> {
// read the id
let id = chisel.u32(Endianness::Little).forward()?;
// read the type tag
let typ = chisel.u8().forward()?;
// parse the type tag, only allowing ones we support
let typ = match typ {
0 => ResourceType::Image,
// ...
5 => ResourceType::Text,
// if we encounter an unknown type, report a format error
ty => return Err(chisel.error(HeaderError::UnknownType(ty), 1))
};
// save the name offaet for reporting later
let name_offset = chisel.offset();
let mut name = Vec::new();
// read the name as a null-terminated string
// note that `name` will not contain the terminating null!
chisel.read_until(0, &mut name).forward()?;
// convert to `String` for ease of use
let name = String::from_utf8(name).map_err(
// if the conversion fails (due to invalid utf-8), report a format error
|_| ChiselError::format(name_offset, HeaderError::IllegalName)
)?;
Ok(ResourceHeader {
id,
typ,
name
})
}Re-exports§
pub use source::ChiselSource;pub use source::ChiselSourceError;
Modules§
Structs§
- Chisel
- An object providing structured access to an underlying byte-stream.
- Chisel
BigEndian - A
Chisel, with big-endian byte order. - Chisel
Error - The error type for chiseling operations.
- Chisel
Little Endian - A
Chisel, with little-endian byte order.
Enums§
- Chisel
Error Data - The error data type for chiseling operations.
- Endianness
- Used to define byte order or “endianness”.
- Read
Until Stop Reason - Used to indicate why a
read_until_or_endoperation stopped.
Traits§
- Infalliable
Format Result Ext - Extension trait for
InfallibleFormatResult.
Type Aliases§
- Chisel
Result - The result type of attempting to chisel a
Tfrom a sourceS, with format errors described byE. - Infallible
Format Error - The error type of attempting to chisel a value from a source
S; where all byte sequences produce valid values (“infallible format”). - Infallible
Format Result - The error type of attempting to chisel a
Tfrom a sourceS. All byte sequences produce validTs (“infallible format”).