簡體   English   中英

我可以使用Bincode反序列化具有可變長度前綴的向量嗎?

[英]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.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM