问题描述
我正在使用Serde和Bincode映射二进制结构.
I'm mapping a binary structure using serde and bincode.
#[macro_use]
extern crate serde_derive;
extern crate serde;
extern crate bincode;
#[derive(Serialize, Deserialize)]
struct Superblock {
magic: [u8; 16],
//reserved: [u8; 492],
crc: u32,
}
一切正常,但我无法映射保留字段.显然,固定大小的数组仅定义为最大32个字节的大小.
Things work as expected, but I can't map the reserved field. Apparently fixed size arrays are only defined for sizes up to 32 bytes.
如何注册自定义大小的数组,以使填充反序列化?
How do I register my custom-sized array so that the padding gets deserialised?
serde + bincode是正确的方法吗?我需要控制字节序提供的字节序,并且我喜欢声明式.
Is serde+bincode the right approach?I need control over endianness (which bincode provides) and I like the declarative style.
推荐答案
我建议实现 和为自定义类型实现Deserialize
.
I'd recommend implementing Serialize
and implementing Deserialize
for a custom type.
要注意的一件大事是,您根本不关心数据.这意味着没有理由占用内存!我们可以定义类型Reserved
,该类型将序列化为一堆字节并从字节反序列化,但实际上在我们的内存结构中不需要任何空间.
The big thing to note is that you don't care about the data at all. This means there's no reason to take up memory! We can define a type Reserved
that will serialize to a bunch of bytes and will deserialize from bytes, but doesn't actually require any space in our in-memory struct.
然后,这只是填充trait实现的问题:
Then, it's just a matter of filling in the trait implementation:
#[macro_use]
extern crate serde_derive;
extern crate serde;
extern crate bincode;
use std::fmt;
use serde::ser::SerializeTuple;
#[derive(Debug, Serialize, Deserialize, PartialEq)]
struct Superblock {
magic: [u8; 16],
reserved: Reserved,
crc: u32,
}
#[derive(Debug, PartialEq)]
struct Reserved;
const RESERVED_LENGTH: usize = 492;
impl serde::Serialize for Reserved {
fn serialize<S>(&self, serializer: S) -> Result<S::Ok, S::Error>
where S: serde::Serializer
{
let mut tuple = serializer.serialize_tuple(RESERVED_LENGTH)?;
for _ in 0..RESERVED_LENGTH {
tuple.serialize_element(&0xA0_u8)?; // Just to see it easily in the output
}
tuple.end()
}
}
impl<'de> serde::Deserialize<'de> for Reserved {
fn deserialize<D>(deserializer: D) -> Result<Self, D::Error>
where D: serde::Deserializer<'de>
{
struct Visitor;
impl<'de> serde::de::Visitor<'de> for Visitor {
type Value = Reserved;
fn expecting(&self, f: &mut fmt::Formatter) -> fmt::Result {
write!(f, "{} bytes", RESERVED_LENGTH)
}
fn visit_seq<A>(self, mut tuple: A) -> Result<Self::Value, A::Error>
where A: serde::de::SeqAccess<'de>,
{
for _ in 0..RESERVED_LENGTH {
tuple.next_element::<u8>()?;
}
Ok(Reserved)
}
}
deserializer.deserialize_tuple(RESERVED_LENGTH, Visitor)
}
}
fn main() {
let block = Superblock {
magic: [
0x00, 0x01, 0x02, 0x03,
0x04, 0x05, 0x06, 0x07,
0x08, 0x09, 0x0a, 0x0b,
0x0c, 0x0d, 0x0e, 0x0f,
],
reserved: Reserved,
crc: 0xffffffff,
};
let ser = bincode::serialize(&block, bincode::Infinite).expect("Couldn't serialize");
println!("length: {}", ser.len());
println!("{:?}", ser);
let block2: Superblock = bincode::deserialize(&ser).expect("Couldn't deserialize");
assert_eq!(block, block2);
println!("{:?}", block2);
println!("Takes: {} bytes", std::mem::size_of::<Superblock>());
// prints "Takes: 20 bytes"
}
这篇关于如何使用Serde和Bincode映射具有32字节填充的C结构?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持!