1use super::*;
2use std::collections::hash_map::*;
3
4pub struct Blobs {
5 map: HashMap<Vec<u8>, u32>,
6 stream: Vec<u8>,
7}
8
9impl Default for Blobs {
10 fn default() -> Self {
11 Self { map: Default::default(), stream: vec![0] }
12 }
13}
14
15impl Blobs {
16 pub fn insert(&mut self, value: &[u8]) -> u32 {
17 if value.is_empty() {
18 return 0;
19 }
20
21 match self.map.entry(value.to_vec()) {
22 Entry::Vacant(entry) => {
23 let offset = *entry.insert(self.stream.len() as u32);
24 let len = value.len();
25 match len {
26 0..=0x7F => self.stream.push(len as u8),
27 0x80..=0x3FFF => {
28 self.stream.push((0x80 | len >> 8) as u8);
29 self.stream.push((0xFF & len) as u8);
30 }
31 _ => {
32 self.stream.push((0xC0 | len >> 24) as u8);
33 self.stream.push((0xFF & len >> 16) as u8);
34 self.stream.push((0xFF & len >> 8) as u8);
35 self.stream.push((0xFF & len) as u8);
36 }
37 }
38 self.stream.extend_from_slice(value);
39 offset
40 }
41 Entry::Occupied(entry) => *entry.get(),
42 }
43 }
44
45 pub fn into_stream(self) -> Vec<u8> {
46 self.stream.into_stream()
47 }
48}
49