Closed jeryaiwei closed 1 year ago
You might have figured it out by now, but here is a small example of how to do that:
use deku::prelude::*;
use dbg_hex::dbg_hex;
pub const ENDIAN_CONSTANT: [u8; 4] = [0x12, 0x34, 0x56, 0x78];
pub const REVERSE_ENDIAN_CONSTANT: [u8; 4] = [0x78, 0x56, 0x34, 0x12];
/// 32-bit unsigned int
#[allow(non_camel_case_types)]
pub type uint = u32;
#[derive(Debug, DekuRead, DekuWrite)]
#[deku(type = "u32", ctx = "endian: deku::ctx::Endian", endian = "endian")]
enum Endian {
Little = 0x12345678,
Big = 0x78563412,
}
impl Endian {
fn to_ctx(&self) -> deku::ctx::Endian {
match self {
Endian::Little => deku::ctx::Endian::Little,
Endian::Big => deku::ctx::Endian::Big,
}
}
}
#[derive(Debug, DekuRead, DekuWrite)]
#[deku(endian = "big")]
pub struct Header {
/// Endianness tag
/// A value of 0x12345678 denotes little-endian, 0x78563412 denotes byte-swapped form.
endian_tag: Endian,
/// Size of the link section, or 0 if this file isn't statically linked
#[deku(endian = "endian_tag.to_ctx()")]
link_size: uint,
}
fn main() {
// Little
let bytes = hex::decode("12345678ff112233").unwrap();
let header = Header::from_bytes((&bytes, 0));
dbg_hex!(header);
// Big
let bytes = hex::decode("78563412ff112233").unwrap();
let header = Header::from_bytes((&bytes, 0));
dbg_hex!(header);
}
Output:
[src/[main.rs:43](http://main.rs:43/)] header = Ok(
(
(
[],
0x0,
),
Header {
endian_tag: Little,
link_size: 0x332211ff,
},
),
)
[src/[main.rs:48](http://main.rs:48/)] header = Ok(
(
(
[],
0x0,
),
Header {
endian_tag: Big,
link_size: 0xff112233,
},
),
)
Closing, lmk if you have any more questions
You might have figured it out by now, but here is a small example of how to do that:
use deku::prelude::*; use dbg_hex::dbg_hex; pub const ENDIAN_CONSTANT: [u8; 4] = [0x12, 0x34, 0x56, 0x78]; pub const REVERSE_ENDIAN_CONSTANT: [u8; 4] = [0x78, 0x56, 0x34, 0x12]; /// 32-bit unsigned int #[allow(non_camel_case_types)] pub type uint = u32; #[derive(Debug, DekuRead, DekuWrite)] #[deku(type = "u32", ctx = "endian: deku::ctx::Endian", endian = "endian")] enum Endian { Little = 0x12345678, Big = 0x78563412, } impl Endian { fn to_ctx(&self) -> deku::ctx::Endian { match self { Endian::Little => deku::ctx::Endian::Little, Endian::Big => deku::ctx::Endian::Big, } } } #[derive(Debug, DekuRead, DekuWrite)] #[deku(endian = "big")] pub struct Header { /// Endianness tag /// A value of 0x12345678 denotes little-endian, 0x78563412 denotes byte-swapped form. endian_tag: Endian, /// Size of the link section, or 0 if this file isn't statically linked #[deku(endian = "endian_tag.to_ctx()")] link_size: uint, } fn main() { // Little let bytes = hex::decode("12345678ff112233").unwrap(); let header = Header::from_bytes((&bytes, 0)); dbg_hex!(header); // Big let bytes = hex::decode("78563412ff112233").unwrap(); let header = Header::from_bytes((&bytes, 0)); dbg_hex!(header); }
Output:
[src/[main.rs:43](http://main.rs:43/)] header = Ok( ( ( [], 0x0, ), Header { endian_tag: Little, link_size: 0x332211ff, }, ), ) [src/[main.rs:48](http://main.rs:48/)] header = Ok( ( ( [], 0x0, ), Header { endian_tag: Big, link_size: 0xff112233, }, ), )
You might have figured it out by now, but here is a small example of how to do that:
use deku::prelude::*; use dbg_hex::dbg_hex; pub const ENDIAN_CONSTANT: [u8; 4] = [0x12, 0x34, 0x56, 0x78]; pub const REVERSE_ENDIAN_CONSTANT: [u8; 4] = [0x78, 0x56, 0x34, 0x12]; /// 32-bit unsigned int #[allow(non_camel_case_types)] pub type uint = u32; #[derive(Debug, DekuRead, DekuWrite)] #[deku(type = "u32", ctx = "endian: deku::ctx::Endian", endian = "endian")] enum Endian { Little = 0x12345678, Big = 0x78563412, } impl Endian { fn to_ctx(&self) -> deku::ctx::Endian { match self { Endian::Little => deku::ctx::Endian::Little, Endian::Big => deku::ctx::Endian::Big, } } } #[derive(Debug, DekuRead, DekuWrite)] #[deku(endian = "big")] pub struct Header { /// Endianness tag /// A value of 0x12345678 denotes little-endian, 0x78563412 denotes byte-swapped form. endian_tag: Endian, /// Size of the link section, or 0 if this file isn't statically linked #[deku(endian = "endian_tag.to_ctx()")] link_size: uint, } fn main() { // Little let bytes = hex::decode("12345678ff112233").unwrap(); let header = Header::from_bytes((&bytes, 0)); dbg_hex!(header); // Big let bytes = hex::decode("78563412ff112233").unwrap(); let header = Header::from_bytes((&bytes, 0)); dbg_hex!(header); }
Output:
[src/[main.rs:43](http://main.rs:43/)] header = Ok( ( ( [], 0x0, ), Header { endian_tag: Little, link_size: 0x332211ff, }, ), ) [src/[main.rs:48](http://main.rs:48/)] header = Ok( ( ( [], 0x0, ), Header { endian_tag: Big, link_size: 0xff112233, }, ), )
thanks,but i think this is not the best method.
this is dex binary header struct; i get endian from endian_tag, how to set endian for header?