[][src]Crate simple_endian

Many byte-order-handling libraries focus on providing code to convert to and from big- or little-endian. However, this requires users of those libraries to use a lot of explicit logic. This library uses the Rust type system to enforce conversions invisibly, and also ensure that they are done consistently. A struct member can be read and written simply using the standard From and Into trait methods (from() and into()). No explicit endian checks are required.

Example 1:

 use simple_endian::*;

 fn init() {
     #[repr(C)]
     struct BinPacket {
         a: u64be,
         b: u32be,
     }
     let mut bp = BinPacket{a: 0xfe.into(), b: 10.into()};
     let new_a = bp.a.to_native() * 1234; 
     bp.a = new_a.into();
     bp.b = 1234.into();
 }

Trying to write bp.a = new_a; causes an error because the type u64 can't be directly stored.

Example 2: Writing a portable struct to a file.

Of course, just storing things in memory isn't that useful unless you write somewhere.

use simple_endian::*;
use std::fs::File;
use std::io::prelude::*;
use std::mem::{transmute, size_of};

// We have to specify a representation in order to define the layout.
#[repr(C)]
struct BinBEStruct {
    pub a: u64be,
    b: u64be,
    c: f64be,
}

fn main() -> std::io::Result<()> {
   let bin_struct = BinBEStruct{a: 345.into(), b: 0xfee.into(), c: 9.345.into()};

   let mut pos = 0;
   let mut data_file = File::create(".test.bin")?;
   let buffer = unsafe { transmute::<&BinBEStruct, &[u8; size_of::<BinBEStruct>()]>(&bin_struct) };

   while pos < buffer.len() {
       let bytes_written = data_file.write(&buffer[pos..])?;
       pos += bytes_written;
   }
   Ok(())
}

Example 3: Mmapping a portable struct with the memmap crate.

You'll need to add memmap to your Cargo.toml to get this to actually work:

#![feature(rustc_private)]
extern crate memmap;

 use std::{
    io::Error,
    fs::OpenOptions,
    mem::size_of,
};

use memmap::MmapOptions;
use simple_endian::*;

#[repr(C)]
struct MyBEStruct {
    header: u64be,
    label: [u8; 8],
    count: u128be,
}

fn main() -> Result<(), Error> {
    let file = OpenOptions::new()
        .read(true).write(true).create(true)
        .open(".test.bin")?;

    // Truncate the file to the size of the header.
    file.set_len(size_of::<MyBEStruct>() as u64)?;
    let mut mmap = unsafe { MmapOptions::new().map_mut(&file)? };

    let mut ptr = mmap.as_mut_ptr() as *mut MyBEStruct;

    unsafe {
        // Set the magic number
        (*ptr).header = 0xfeedface.into();

        // Increment the counter each time we run.
        (*ptr).count += 1.into();

        (*ptr).label = *b"Iamhere!";
    }

    println!("done.");
    Ok(())
}

Structs

BigEndian

A big-endian representation of type T that implements SpecificEndian. Data stored in the struct must be converted to big-endian using from() or into().

LittleEndian

A little-endian representation of type T that implements SpecificEndian. Data stored in the struct must be converted to little-endian using from() or into().

Traits

SpecificEndian

Any object implementing SpecificEndian can be converted between big and little endian. Implement this trait to allow for endian conversion by this crate.

Type Definitions

f32le

Shorthand for LittleEndian

f32be

Shorthand for BigEndian

f64le

Shorthand for LittleEndian

f64be

Shorthand for BigEndian

i16le

Shorthand for LittleEndian

i16be

Shorthand for BigEndian

i32le

Shorthand for LittleEndian

i32be

Shorthand for BigEndian

i64le

Shorthand for LittleEndian

i64be

Shorthand for BigEndian

i128le

Shorthand for LittleEndian

i128be

Shorthand for BigEndian

isizebe

Shorthand for BigEndian

isizele

Shorthand for LittleEndian

u16le

Shorthand for LittleEndian

u16be

Shorthand for BigEndian

u32le

Shorthand for LittleEndian

u32be

Shorthand for BigEndian

u64le

Shorthand for LittleEndian

u64be

Shorthand for BigEndian

u128le

Shorthand for LittleEndian

u128be

Shorthand for BigEndian

usizebe

Shorthand for BigEndian

usizele

Shorthand for LittleEndian