cyfs_base/codec/raw/
raw_codec.rs

1use crate::*;
2
3use std::any::Any;
4
5//能静态确定编码后大小
6pub trait RawFixedBytes {
7    fn raw_bytes() -> Option<usize> {
8        None
9    }
10    fn raw_max_bytes() -> Option<usize> {
11        Self::raw_bytes()
12    }
13    fn raw_min_bytes() -> Option<usize> {
14        Self::raw_bytes()
15    }
16}
17
18/*
19// TODO rust stable稳定版本支持模板偏特化后,再把raw_hash_code从RawEncode里面提取出来单独的trait
20pub trait RawHashCode {
21    fn raw_hash_encode(&self) -> BuckyResult<HashValue>;
22}
23
24
25impl<T: RawEncode> RawHashCode for T {
26    fn raw_hash_encode(&self) -> BuckyResult<HashValue> {
27        let size = self.raw_measure(&None)?;
28        let mut buf = vec![0u8;size];
29
30        let remain_buf = self.raw_encode(&mut buf, &None)?;
31        let remain_len = remain_buf.len();
32        let encoded_buf = &buf[..(buf.len() - remain_len)];
33
34        let hash = hash_data(encoded_buf);
35
36        let hash_slice = unsafe { &*(hash.as_slice().as_ptr() as *const [u8; 32]) };
37        Ok(HashValue::from(hash_slice))
38    }
39}
40*/
41
42#[derive(Debug, Clone, Eq, PartialEq)]
43pub enum RawEncodePurpose {
44    // 默认值,为序列化而编码,需要是完整编码
45    Serialize,
46
47    // 为计算hash而编码
48    Hash,
49}
50
51#[derive(Debug, Clone)]
52pub struct RawDecodeOption {
53    pub version: u8,
54    pub format: u8,
55}
56
57impl Default for RawDecodeOption {
58    fn default() -> Self {
59        Self {
60            version: 0,
61            format: OBJECT_CONTENT_CODEC_FORMAT_RAW,
62        }
63    }
64}
65
66//编码
67pub trait RawEncode {
68    fn raw_measure(&self, purpose: &Option<RawEncodePurpose>) -> BuckyResult<usize>;
69    fn raw_encode<'a>(
70        &self,
71        buf: &'a mut [u8],
72        purpose: &Option<RawEncodePurpose>,
73    ) -> BuckyResult<&'a mut [u8]>;
74    fn raw_tail_encode<'a>(
75        &self,
76        buf: &'a mut [u8],
77        purpose: &Option<RawEncodePurpose>,
78    ) -> BuckyResult<&'a [u8]> {
79        let remain_buf = self.raw_encode(buf, purpose)?;
80        let remain_len = remain_buf.len();
81        Ok(&buf[..(buf.len() - remain_len)])
82    }
83
84    // 直接编码到buffer
85    fn raw_encode_to_buffer(&self) -> BuckyResult<Vec<u8>> {
86        let size = self.raw_measure(&None)?;
87        let mut encode_buf = vec![0u8; size];
88
89        let buf = self.raw_encode(&mut encode_buf, &None)?;
90        assert_eq!(buf.len(), 0);
91
92        Ok(encode_buf)
93    }
94
95    // 计算对象的hash
96    fn raw_hash_value(&self) -> BuckyResult<HashValue> {
97        let encoded_buf = self.raw_hash_encode()?;
98        Ok(self.hash_buf(&encoded_buf))
99    }
100
101    fn hash_buf(&self, encoded_buf: &[u8]) -> HashValue {
102        hash_data(encoded_buf)
103    }
104
105    // 默认hash编码实现,子类可以覆盖
106    fn raw_hash_encode(&self) -> BuckyResult<Vec<u8>> {
107        let size = self.raw_measure(&Some(RawEncodePurpose::Hash))?;
108        let mut buf = vec![0u8; size];
109        let remain_buf = self.raw_encode(&mut buf, &Some(RawEncodePurpose::Hash))?;
110        assert!(remain_buf.len() == 0);
111
112        Ok(buf)
113    }
114}
115
116pub trait RawEncodeWithContext<Context> {
117    fn raw_measure_with_context(
118        &self,
119        _: &mut Context,
120        purpose: &Option<RawEncodePurpose>,
121    ) -> BuckyResult<usize>;
122    fn raw_encode_with_context<'a>(
123        &self,
124        buf: &'a mut [u8],
125        _: &mut Context,
126        purpose: &Option<RawEncodePurpose>,
127    ) -> BuckyResult<&'a mut [u8]>;
128    fn raw_tail_encode_with_context<'a>(
129        &self,
130        buf: &'a mut [u8],
131        context: &mut Context,
132        purpose: &Option<RawEncodePurpose>,
133    ) -> BuckyResult<&'a [u8]> {
134        let remain_buf = self.raw_encode_with_context(buf, context, purpose)?;
135        let remain_len = remain_buf.len();
136        Ok(&buf[..(buf.len() - remain_len)])
137    }
138}
139
140//解码
141pub trait RawDecode<'de>: Sized {
142    // 不带opt的解码,默认一般实现此方法
143    fn raw_decode(buf: &'de [u8]) -> BuckyResult<(Self, &'de [u8])>;
144
145    // 带opt的解码,如果想使用版本等高级解码特性,需要实现此方法
146    fn raw_decode_with_option(
147        buf: &'de [u8],
148        _opt: &RawDecodeOption,
149    ) -> BuckyResult<(Self, &'de [u8])> {
150        Self::raw_decode(buf)
151    }
152
153    /*
154    fn raw_hash_decode(buf: &'de [u8]) -> BuckyResult<(Self, &'de [u8], HashValue)> {
155        let (v, next_buf) = Self::raw_decode(buf)?;
156        let hash = hash_data(&buf[..(buf.len() - next_buf.len())]);
157        let hash_slice = unsafe { &*(hash.as_slice().as_ptr() as *const [u8; 32]) };
158        Ok((v, next_buf, HashValue::from(hash_slice)))
159    }
160    */
161}
162
163pub trait RawDecodeWithContext<'de, Context>: Sized {
164    fn raw_decode_with_context(buf: &'de [u8], _: Context) -> BuckyResult<(Self, &'de [u8])>;
165
166    /*
167    fn raw_hash_decode_with_context(
168        buf: &'de [u8],
169        context: Context,
170    ) -> BuckyResult<(Self, &'de [u8], HashValue)> {
171        let (v, next_buf) = Self::raw_decode_with_context(buf, context)?;
172        let hash = hash_data(&buf[..(buf.len() - next_buf.len())]);
173        let hash_slice = unsafe { &*(hash.as_slice().as_ptr() as *const [u8; 32]) };
174        Ok((v, next_buf, HashValue::from(hash_slice)))
175    }
176    */
177}
178
179pub trait RawMergable: Clone + Any {
180    fn raw_merge_ok(&self, other: &Self) -> bool;
181}
182
183impl<T: RawEncode + Eq + Clone + Any> RawMergable for T {
184    fn raw_merge_ok(&self, other: &Self) -> bool {
185        self.eq(other)
186    }
187}
188
189#[cfg(test)]
190mod test {
191    use crate::*;
192
193    #[test]
194    fn test_hash() {
195        let buf = "test_hash_buf".as_bytes();
196        let hash = hash_data(buf);
197
198        let hash_slice = unsafe { &*(hash.as_slice().as_ptr() as *const [u8; 32]) };
199    
200        let hash2 = HashValue::from(hash_slice);
201        assert_eq!(hash, hash2);
202    }
203}