0.0.1 |
|
---|
#114 in #file-io
11KB
302 行
ApeBDLM
Binary-Data-Layout-Macros,宏,用于辅助创建二进制数据向量,使其更易于阅读。
在创建此包时,我遇到了一个需要解决的问题;在将二进制数据存储到文件之前,没有一种干净的方式来组织这些数据。
您可以 只 按顺序写入一切,或者将所有内容推送到一个向量并写入它(我正在做的事情),但这通常会变得很丑陋,虽然读起来不难,但我感觉不小心搞乱重要数据字节顺序的可能性并不小
例如,如果您想向文件写入三个字符串,您可以这样做
let data = Vec::<u8>::new();
data.push(len1);
data.extend_from_slice(string1);
data.push(len2);
data.extend_from_slice(string2);
data.push(len3);
data.extend_from_slice(string3);
file.write_all(&data)?;
但是,就我个人而言,这相当丑陋,难以与其他代码区分开来,并且对于文件的一个非常结构化的部分来说,结构也不是很好。
因此,我创建了一组宏,可以用来自动化二进制数据的结构,使其以 安全、结构化和可读 的方式存在。以下是上面的相同代码,但使用了 ApeBDLM
let data = binary_data!
(
byte!(len1),
bytes_from_vec!(string1),
byte!(len2),
bytes_from_vec!(string2),
byte!(len3),
bytes_from_vec!(string3)
);
file.write_all(&data)?;
数据不仅结构更好,而且与代码分离,而且如果有任何错误或数据结构错误,由于缺少不必要的 .push 或 .extend_from_slice 代码阻塞您的视野,因此将很容易找到并修复它。
用法
此包允许以简单和结构化的方式创建二进制数据向量,并且由于其简单性,使用起来相当容易。`binary_data!
` 宏基本上只是创建一个新的向量并将括号内的所有数据转换为向量并添加到其中。 注意 只有此库提供的其他宏,如 `byte!
` 和 `i32_be!
`,可以作为 `binary_data!
` 宏的参数。
以下是已经适应此库的代码示例
import apebdlm::*;
// Lines 2-528 stay the same
pub(crate) fn write_chunk<W: Write>(mut w: W, name: chunk::ChunkType, data: &[u8]) -> Result<()> {
let mut crc = Crc32::new();
crc.update(&name.0);
crc.update(data);
let buffer = binary_data!(
u32_be!(data.len),
bytes_from_vec!(&name.0),
bytes_from_vec!(data),
u32_be!(crc.finalize())
);
w.write_all(&buffer)?;
Ok(())
}
// Etc...
代码示例归功于 rust png 库,具体来说,第 528-538 行已适配此示例。