[][src]Crate byteordered

This crate provides an alternative API for reading and writing data in an endianness that might only be known at run-time. It encapsulates the existing capabilities of the byteorder crate with an interface that assumes an implicitly acknowledged byte order.

The benefits of this API is two-fold. This crate supports use cases where the data's endianness is only known during program execution, which may happen in some formats and protocols. The same API can be used to reduce redundancy by indicating the intended byte order once for the entire routine, instead of once for each method call.

The main contribution in this crate is the ByteOrdered wrapper type, which infuses byte order information to a data source or destination (it works for both readers and writers). Moreover, the Endian trait contains multiple primitive data reading and writing methods, and the Endianness type provides a basic enumerate for endianness information only known at run-time.

Examples

Use one of ByteOrdered's constructors to create a wrapper with byte order awareness.

use byteordered::{ByteOrdered, Endianness};

let mut rd = ByteOrdered::le(get_data_source()?); // little endian
// read a u16
let w = rd.read_u16()?;
// choose to read the following data in Little Endian if it's
// smaller than 256, otherwise read in Big Endian
let mut rd = rd.into_endianness(Endianness::le_iff(w < 256));
let value: u32 = rd.read_u32()?;

Both byteordered and byteorder work well side by side. You can use byteorder in one part of the routine, and wrap the reader or writer when deemed useful.

use byteorder::ReadBytesExt;
use byteordered::{ByteOrdered, Endianness};

let b = 5;
// choose to read the following data in Little Endian if it's 0,
// otherwise read in Big Endian (what happens in this case)
let mut wt = ByteOrdered::runtime(
    Vec::new(),
    if b == 0 { Endianness::Little } else { Endianness::Big }
);
// write in this byte order
wt.write_u16(0xC000)?;
wt.write_u32(0)?;
// then invert the byte order
let mut wt = wt.into_opposite();
wt.write_u16(0xEEFF)?;
assert_eq!(&*wt.into_inner(), &[0xC0, 0, 0, 0, 0, 0, 0xFF, 0xEE]);

As an additional construct, the with_order! macro is another API for reading and writing data, with the perk of providing explicit monomorphization with respect to the given endianness.

with_order!(get_data_source()?, Endianness::Little, |rd| {
    let value: u32 = rd.read_u32()?;
    println!("-> {}", value);
});

Features

i128 enables reading and writing 128-bit integers, as in byteorder. This library requires the standard library (no_std is currently not supported).

Re-exports

pub extern crate byteorder;

Macros

with_order

Creates a monomorphized scope for reading or writing with run-time byte order awareness.

Structs

ByteOrdered

Wrapper type for a reader or writer with an assumed byte order.

StaticEndianness

A data type representing a byte order known in compile time. Unlike the types provided in byteorder, this type can be constructed.

Enums

Endianness

Enumerate for materializing the two kinds of machine byte order supported by Rust.

Traits

Endian

General trait for types that can serialize and deserialize bytes in some byte order. It roughly resembles byteorder::ByteOrder, with the exception that it is implemented for material types. This makes it possible to embed byte order information to a reader or writer by composition (which is done by ByteOrdered).