#read-write #traits #data #io-write #endianness #packed #packer

bytepack

bytepack为任何打包数据类型提供通用的读写特征扩展

7个不稳定版本 (3个重大变更)

使用旧的Rust 2015

0.4.1 2017年5月21日
0.4.0 2017年5月21日
0.3.1 2017年4月1日
0.2.0 2017年3月20日
0.1.1 2017年3月19日

#1549 in 编码

Download history 201/week @ 2024-03-13 112/week @ 2024-03-20 134/week @ 2024-03-27 217/week @ 2024-04-03 149/week @ 2024-04-10 199/week @ 2024-04-17 140/week @ 2024-04-24 249/week @ 2024-05-01 93/week @ 2024-05-08 115/week @ 2024-05-15 110/week @ 2024-05-22 97/week @ 2024-05-29 125/week @ 2024-06-05 112/week @ 2024-06-12 235/week @ 2024-06-19 140/week @ 2024-06-26

每月下载量 624次
用于 7 个crate (4 个直接使用)

MIT 许可证

47KB
958

bytepack

Crates.io Build Status Docs.rs

bytepack 是一个简单的crate,它扩展了 std::io API,能够读取和写入任何数据类型的内存表示形式。它被视为 std::io::Readstd::io::Write 特征的泛化,但操作的是泛型参数 T 而不是 u8。这个crate通过无拷贝(除了一个明确标记的案例)并提供了读取和写入数组的方法,专注于性能。

bytepack 提供了三个特征家族,允许不同的字节序控制。 UnpackerPacker 在操作系统的字节序中读取和写入数据。 LEUnpackerLEPacker 总是在小端字节序中读取和写入数据,而 BEUnpackerBEPacker 在大端字节序中执行相同的操作。它们都符合相同的API,该API是从 std::io 复制的。这意味着只需将不同的特征引入作用域,就可以在不同的字节序之间切换。

因为 bytepack 不是一个序列化库,它不能直接从Reader或Writer读取和写入像 VecRc 等复杂类型。实际上,这些类型并不直接包含打包在内部的数据,而是持有对它的引用或指针。为了识别持有其数据“打包”在一起的数据类型,使用 Packed 特征。此外,它还提供了一种原地字节序切换方法。可以为被认为安全读取和写入的数据类型实现此特征。在 bytepack_derive crate 中还实现了仅由实现 Packed 的类型组成的结构的自动派生。

示例

这里有两个函数,可以将 Vec<f32> 序列化和反序列化

extern crate bytepack;

use std::fs::File;
use std::iter::repeat;

use bytepack::{LEPacker, LEUnpacker};

fn write_samples(file: &str, samples: &Vec<f32>) {
    let mut file = File::create(file).unwrap();
    file.pack(samples.len() as u32).unwrap();
    file.pack_all(&samples[..]).unwrap();
}

fn read_samples(file: &str) -> Vec<f32> {
    let mut file = File::open(file).unwrap();
    let num_samples : u32 = file.unpack().unwrap();
    let mut samples : Vec<f32> = repeat(0f32).take(num_samples as usize).collect();
    file.unpack_exact(&mut samples[..]).unwrap();
    return samples;
}

得益于 Packed 特质的泛型性,我们可以使之前的函数泛型化

extern crate bytepack;

use std::fs::File;

use bytepack::{LEPacker, Packed};

fn write_vec<T: Packed + Clone>(file: &str, samples: &Vec<T>) {
    let mut file = File::create(file).unwrap();
    file.pack(samples.len() as u32).unwrap();
    file.pack_all(&samples[..]).unwrap();
}

因为我们可以为我们自己的结构体派生 Packed,所以我们可以使用我们自己的类型

extern crate bytepack;
#[macro_use]
extern crate bytepack_derive;

use std::fs::File;

use bytepack::{LEPacker, Packed};

#[derive(Packed, Clone)]
struct Vertex<T: Packed> {
    x: T,
    y: T,
    z: T
}

fn write_vec<T: Packed + Clone>(file: &str, samples: &Vec<T>) {
    let mut file = File::create(file).unwrap();
    file.pack(samples.len() as u32).unwrap();
    file.pack_all(&samples[..]).unwrap();
}

fn main() {
    let square : Vec<Vertex<f32>> = vec![
        Vertex{x: 0.0, y: 0.0, z: 0.0},
        Vertex{x: 1.0, y: 0.0, z: 0.0},
        Vertex{x: 1.0, y: 1.0, z: 0.0},
        Vertex{x: 0.0, y: 1.0, z: 0.0},
    ];

    write_vec("square.raw", &square);
}

依赖项

~1.5MB
~41K SLoC