reifydb_codec/primitive/
blob.rs1use reifydb_value::{
5 reifydb_assertions,
6 value::{blob::Blob, value_type::ValueType},
7};
8
9use crate::row::{bytes::RowBuilder, shape::RowShape};
10
11impl RowShape {
12 pub fn set_blob(&self, row: &mut impl RowBuilder, index: usize, value: &Blob) {
13 self.set_blob_from_slice(row, index, value.as_bytes());
14 }
15
16 pub fn set_blob_from_slice(&self, row: &mut impl RowBuilder, index: usize, bytes: &[u8]) {
17 reifydb_assertions! {
18 assert!(
19 row.len() >= self.total_static_size(),
20 "row/shape size mismatch: row.len()={} < total_static_size()={}",
21 row.len(),
22 self.total_static_size()
23 );
24 assert_eq!(*self.fields()[index].constraint.get_type().inner_type(), ValueType::Blob);
25 }
26 self.replace_dynamic_data(row, index, bytes);
27 }
28
29 pub fn get_blob(&self, row: &[u8], index: usize) -> Blob {
30 Blob::from_slice(self.get_blob_slice(row, index))
31 }
32
33 pub fn get_blob_slice<'a>(&self, row: &'a [u8], index: usize) -> &'a [u8] {
34 let field = &self.fields()[index];
35 reifydb_assertions! {
36 assert!(
37 row.len() >= self.total_static_size(),
38 "row/shape size mismatch: row.len()={} < total_static_size()={}",
39 row.len(),
40 self.total_static_size()
41 );
42 assert_eq!(*field.constraint.get_type().inner_type(), ValueType::Blob);
43 }
44
45 let ref_slice = &row[field.offset as usize..field.offset as usize + 8];
46 let offset = u32::from_le_bytes([ref_slice[0], ref_slice[1], ref_slice[2], ref_slice[3]]) as usize;
47 let length = u32::from_le_bytes([ref_slice[4], ref_slice[5], ref_slice[6], ref_slice[7]]) as usize;
48
49 let dynamic_start = self.dynamic_section_start();
50 let blob_start = dynamic_start + offset;
51 &row[blob_start..blob_start + length]
52 }
53
54 pub fn get_blob_slice_builder<'a>(&self, row: &'a impl RowBuilder, index: usize) -> &'a [u8] {
55 let field = &self.fields()[index];
56 let buffer = row.as_slice();
57 let ref_slice = &buffer[field.offset as usize..field.offset as usize + 8];
58 let offset = u32::from_le_bytes([ref_slice[0], ref_slice[1], ref_slice[2], ref_slice[3]]) as usize;
59 let length = u32::from_le_bytes([ref_slice[4], ref_slice[5], ref_slice[6], ref_slice[7]]) as usize;
60 let blob_start = self.dynamic_section_start() + offset;
61 &buffer[blob_start..blob_start + length]
62 }
63
64 pub fn get_blob_slice_mut<'a>(&self, row: &'a mut [u8], index: usize) -> &'a mut [u8] {
65 let field = &self.fields()[index];
66 reifydb_assertions! {
67 assert!(
68 row.len() >= self.total_static_size(),
69 "row/shape size mismatch: row.len()={} < total_static_size()={}",
70 row.len(),
71 self.total_static_size()
72 );
73 assert_eq!(*field.constraint.get_type().inner_type(), ValueType::Blob);
74 }
75
76 let ref_slice = &row[field.offset as usize..field.offset as usize + 8];
77 let offset = u32::from_le_bytes([ref_slice[0], ref_slice[1], ref_slice[2], ref_slice[3]]) as usize;
78 let length = u32::from_le_bytes([ref_slice[4], ref_slice[5], ref_slice[6], ref_slice[7]]) as usize;
79
80 let blob_start = self.dynamic_section_start() + offset;
81 &mut row[blob_start..blob_start + length]
82 }
83
84 pub fn try_get_blob(&self, row: &[u8], index: usize) -> Option<Blob> {
85 if self.is_defined(row, index) && self.fields()[index].constraint.get_type() == ValueType::Blob {
86 Some(self.get_blob(row, index))
87 } else {
88 None
89 }
90 }
91}