#structs #deserialize #serialization #syscalls #codec #ffi #data-encoding

packed-encoder

一个小巧的rust crate,可以将不同类型的数据编码成一个打包的字节数组,该数组可以用于网络传输、系统调用或FFI。

2个版本

0.1.1 2022年10月31日
0.1.0 2022年10月31日

#919 in 编码

自定义许可

38KB
725

packed-encoder

一个小巧的rust crate,可以将不同类型的数据编码成一个打包的字节数组,该数组可以用于网络传输、系统调用或FFI。该库产生的字节数组可以被转换为类似C的打包结构体。

安装

该crate已发布在crates.io上,请查看

  1. crates.io crate
  2. docs.rs 文档

要将packed-encoder添加到crates.io,请将以下条目添加到Cargo.toml文件中的dependencies部分

[dependencies]
packed-encoder = "0.1.1"

编码

您可以将需要编码的值集传递到字节数组中。如下所示

extern crate packed_encoder;

use packed_encoder::encoder;

fn main() {
    // list of values to encode
    let to_encode = &[
        encoder::EncodeType::Int128(-234984564544),
        encoder::EncodeType::Str("this-is-good".to_owned()),
        encoder::EncodeType::Uint64(837477899),
        encoder::EncodeType::Int8(10),
        encoder::EncodeType::Bytes(vec![0xff, 0xab, 0x12, 0x33]),
    ];
    // encode the values the result will be of type `Result<Vec<u8>, EncodeError>`
    let encoded_result = encoder::encode_packed(to_encode, encoder::EncodeOrder::Little);
    assert_eq!(encoded_result.is_ok(), true);
    println!("bytes={:?}", encoded_result.unwrap());
}

解码

您可以将字节数组传递给解码器,并传递所需的数据类型以获取解码后的数据,如下所示

 extern crate packed_encoder;
 use packed_encoder::decoder;

 fn main() {

     // byte data to decode
     let bytes = vec![192, 24, 212, 73, 201, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 116, 104, 105, 115, 45, 105, 115, 45, 103, 111, 111, 100, 11, 230, 234, 49, 0, 0, 0, 0, 10, 255, 171, 18, 51];
     // required types to decode from the given byte array
     let required_types = &[
            decoder::DecodeType::Int128,
            decoder::DecodeType::Str(12),
            decoder::DecodeType::Uint64,
            decoder::DecodeType::Int8,
            decoder::DecodeType::Bytes(4),
        ];
     
     // decode
     let result = decoder::decode_packed(required_types, &bytes, decoder::DecodeOrder::Little);
     assert_eq!(result.is_ok(), true);

     // check values
     let decoded_data = result.unwrap();
     match &decoded_data[1] {
         decoder::DecodedData::Str(content) => {println!("decoded string at position 1: {}", content)},
         _ => {}
     }

 }

结构体互操作性

解码器获取的字节数组可以被转换为任何打包的结构体。下面是一个示例。

extern crate packed_encoder;

use packed_encoder::encoder;

fn test_struct_interoperability() {
    #[repr(C, packed)]
    struct Sample {
        pub x: u8,
        pub y: [u8; 5],
        pub z: i64,
        pub a: [char; 5],
    }

    let to_encode = &[
        encoder::EncodeType::Uint8(100),
        encoder::EncodeType::Bytes(vec![0, 1, 2, 3, 4]),
        encoder::EncodeType::Int64(256),
        encoder::EncodeType::Str("hello".to_owned()),
    ];

    let encode_result = encoder::encode_packed(to_encode, encoder::EncodeOrder::Little);
    assert_eq!(encode_result.is_ok(), true);

    let encoded_data = encode_result.unwrap();

    unsafe {
        let sample: *const Sample = encoded_data.as_ptr() as *const Sample;
        assert_eq!((*sample).x == 100, true);
        assert_eq!((*sample).y == [0, 1, 2, 3, 4], true);
        assert_eq!((*sample).z == 256, true);
    }
}

运行测试和文档

要验证此crate的功能,请使用cargo运行测试

cargo test

要本地查看此crate的文档

cargo doc --open

贡献

请随时提出问题、提交PR和提出改进建议,或建议替代库。

依赖项

~115KB