pub trait DecastIO {
fn decast<T>(&mut self, val_ptr: &T) -> Result<usize>
where
T: Cast;
fn decastf<T>(&mut self, val_ptr: &T, endian: Endian) -> Result<usize>
where
T: Cast + Flip;
fn decasts<T>(&mut self, slice: &[T]) -> Result<usize>
where
T: Cast;
fn decastsf<T>(&mut self, slice: &[T], endian: Endian) -> Result<usize>
where
T: Cast + Flip;
fn decastv<T>(&mut self, slice: &[T]) -> Result<usize>
where
T: Cast;
fn decastvf<T>(&mut self, slice: &[T], endian: Endian) -> Result<usize>
where
T: Cast + Flip;
}
Expand description
Defines methods to decast
and endian-flip
through io::Write
.
Note: In this crate, the term encast
means decoding a number of
bytes to one or more values, the term decast
means encoding one
or more variables to a number of bytes, and the term endian-flip
means flipping the endianness of value(s).
Example 1
In the example below, method decastf
encodes the value in
udp_hdr1
of type UdpHdr
to bytes in Big-Endian (BE
) and
stores them in bytes2
. Note that io::Cursor
wraps an
in-memory buffer and provides it through io::Write
.
use std::io::Cursor;
use castflip::{Cast, Flip, DecastIO, BE};
#[repr(C)]
#[derive(Cast, Flip)]
struct UdpHdr { // UDP: https://www.rfc-editor.org/rfc/rfc768.txt
sport: u16, // UDP Source Port
dport: u16, // UDP Destination Port
len: u16, // UDP Length
sum: u16, // UDP Checksum
}
// Input data: UDP header (8 bytes)
let udp_hdr1 = UdpHdr { sport: 50121, dport: 53, len: 50, sum: 0x823F };
// Encode UDP header `udp_hdr1` to bytes in `output2`.
// Because the UDP header is 8 bytes as defined above,
// only the first 8 bytes of `output2` are filled with data.
let mut output2 = Cursor::new(vec![0_u8; 16]);
let size2 = output2.decastf(&udp_hdr1, BE)?;
let bytes2 = output2.into_inner();
// `udp_hdr1` should be encoded as following (8 bytes)
let bytes3: [u8; 8] = [0xC3, 0xC9, 0x00, 0x35, 0x00, 0x32, 0x82, 0x3F];
// Check the results (bytes2)
assert_eq!(size2, 8);
assert_eq!(&bytes2[0..8], &bytes3[0..8]);
assert_eq!(&bytes2[8..16], &[0_u8; 8]);
Description
All methods in trait DecastIO
decast
one or more variables to
a number of bytes and writes to I/O. The type of the value(s) can
be explicitly specified as the generic type parameter of its
method or simply omitted because the Rust compiler can infer from
the argument. The methods whose name contain ‘s’ (= slice) or ‘v’
(= vector) decast
to a series of structured binary data. The
methods whose names end with ‘f’ flip the endianness of the
results. Currently, an implementation for trait io::Write
is
provided.
The output self
should have enough room to encode to the
specified number of value(s) of the specified type T
. If there
is enough room, the specified variable(s) is/are encoded to bytes
and written to output self
. If successful, the size of written
bytes is returned in Ok
(). If I/O error is detected,
Err
(io::Error
) is returned. The type of the return value is
io::Result
.
When argument endian
is specified, the endianness of resulting
bytes is flipped if necessary.
Example 2
Because io::Write
is implemented for &[u8]
, DecastIO
can
decast
to memory. The example below is almost the same with
Example 1 except it uses a mutable slice instead of io::Cursor
.
use castflip::{Cast, Flip, DecastIO, BE};
#[repr(C)]
#[derive(Cast, Flip)]
struct UdpHdr { // UDP: https://www.rfc-editor.org/rfc/rfc768.txt
sport: u16, // UDP Source Port
dport: u16, // UDP Destination Port
len: u16, // UDP Length
sum: u16, // UDP Checksum
}
// Input data: UDP header (8 bytes)
let udp_hdr1 = UdpHdr { sport: 50121, dport: 53, len: 50, sum: 0x823F };
// Encode UDP header `udp_hdr1` to bytes in `output2`.
// Because the UDP header is 8 bytes as defined above,
// only the first 8 bytes of `output2` are filled with data.
let mut bytes2 = [0_u8; 16];
let mut slice2 = &mut bytes2[..];
let size2 = slice2.decastf(&udp_hdr1, BE)?;
// `udp_hdr1` should be encoded as following (8 bytes)
let bytes3: [u8; 8] = [0xC3, 0xC9, 0x00, 0x35, 0x00, 0x32, 0x82, 0x3F];
// Check the result (slice2)
// Note: `slice2` contains unwritten part.
assert_eq!(slice2.len(), 8);
assert_eq!(slice2, [0_u8; 8]);
// Check the results (bytes2)
assert_eq!(size2, 8);
assert_eq!(&bytes2[0..8], &bytes3[0..8]); // Written part
assert_eq!(&bytes2[8..16], &[0_u8; 8]); // Unwritten part
Required Methods
Encodes the value pointed by val_ptr
of type T
to bytes
and writes them to output self
. The endianness of the
resulting bytes is not flipped.
Encodes the value pointed by val_ptr
of type T
to bytes
and writes them to output self
. The endianness of the
resulting bytes is flipped if necessary. The endianness of
the resulting bytes is specified in endian
.
Encodes value(s) in slice
of type T
to bytes and writes
them to output self
. The endianness of the resulting bytes
is not flipped.
Encodes value(s) in slice
of type T
to bytes and writes
them to output self
. The endianness of the resulting bytes
is flipped if necessary. The endianness of the resulting
bytes is specified in endian
.
Encodes value(s) in slice
of type T
to bytes and writes
them to output self
. The endianness of the resulting bytes
is not flipped.
(This method is replaced by decasts
)
Encodes value(s) in slice
of type T
to bytes and writes
them to output self
. The endianness of the resulting bytes
is flipped if necessary. The endianness of the resulting
bytes is specified in endian
.
(This method is replaced by decastsf
)