[英]Can I deserialize vectors with variable length prefix with Bincode?
我在Rust Bincode庫上遇到問題。 序列化向量時,始終假設前綴長度為8個字節。 當您始終使用bincode編碼數據時,這是一個很好的假設,因為bincode可以讀取它自己的序列化數據。
我處於無法影響串行器的情況,因為我沒有編寫串行器,並且由於遺留原因,它必須保持不變。 它將其矢量編碼為一個長度為前綴的數組,其中的前綴始終為2個字節(或者在某些情況下為4個字節,但是我知道這些情況。一旦我知道如何使用2個字節來做,則4個字節不應為問題)。
如何使用Bincode(和Serde)來反序列化這些字段? 我可以解決以二進制編碼硬編碼的默認8個字節的長度嗎?
Bincode不應與任何現有的序列化器或標准兼容。 根據評論,您嘗試讀取的格式也不是。
我建議您獲得二進制代碼源(它們是MIT許可的,因此您基本上可以隨心所欲地隨意使用它們)並對其進行修改以適合您的格式(並為其命名並包括在您的項目中)。
serde::Deserializer
和基礎數據模型都有很好的文檔說明,在bincode中的實現很難找到(在de/mod.rs
),因此以它為起點並根據需要進行調整。
我想出了一種(可能非常丑陋的)方式來實現它,而無需實現自己的解串器-畢竟Bincode可以做到。 看起來像這樣:
impl<'de> Deserialize<'de> for VarLen16 {
fn deserialize<D>(deserializer: D) -> Result<Self, D::Error>
where
D: Deserializer<'de>,
{
struct VarLen16Visitor;
impl<'de> Visitor<'de> for VarLen16Visitor {
type Value = VarLen16;
fn expecting(&self, formatter: &mut fmt::Formatter) -> fmt::Result {
formatter.write_str("VarLen16")
}
fn visit_seq<A>(self, mut seq: A) -> Result<Self::Value, A::Error>
where
A: SeqAccess<'de>,
{
let mut res: Vec<u8> = vec![];
let length: u16 = seq
.next_element()?
.ok_or_else(|| serde::de::Error::invalid_length(1, &self))?;
for i in 0..length {
res.push(
seq.next_element()?
.ok_or_else(|| serde::de::Error::invalid_length(1, &self))?,
);
}
return Ok(VarLen16(res));
}
}
return Ok(deserializer.deserialize_tuple(1 << 16, VarLen16Visitor)?);
}
}
簡而言之,我讓系統認為我反序列化了一個元組,在其中將長度設置為所需的最大值。 我已經測試過了,它實際上並沒有分配那么多的內存。 然后,我將長度表示為該元組的一部分,先閱讀該長度,然后繼續閱讀直到該長度指示我為止。 它雖然不漂亮,但肯定可以。
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.