Skip to main content

reifydb_codec/primitive/
blob.rs

1// SPDX-License-Identifier: Apache-2.0
2// Copyright (c) 2026 ReifyDB
3
4#[cfg(reifydb_assertions)]
5use reifydb_value::value::value_type::ValueType;
6use reifydb_value::{reifydb_assertions, value::blob::Blob};
7
8use crate::row::{bytes::RowBuilder, shape::RowShape};
9
10impl RowShape {
11	pub fn set_blob(&self, row: &mut impl RowBuilder, index: usize, value: &Blob) {
12		self.set_blob_from_slice(row, index, value.as_bytes());
13	}
14
15	pub fn set_blob_from_slice(&self, row: &mut impl RowBuilder, index: usize, bytes: &[u8]) {
16		reifydb_assertions! {
17			assert!(
18				row.len() >= self.total_static_size(),
19				"row/shape size mismatch: row.len()={} < total_static_size()={}",
20				row.len(),
21				self.total_static_size()
22			);
23			assert_eq!(*self.fields()[index].constraint.get_type().inner_type(), ValueType::Blob);
24		}
25		self.replace_dynamic_data(row, index, bytes);
26	}
27
28	pub fn get_blob(&self, row: &[u8], index: usize) -> Blob {
29		Blob::from_slice(self.get_blob_slice(row, index))
30	}
31
32	pub fn get_blob_slice<'a>(&self, row: &'a [u8], index: usize) -> &'a [u8] {
33		let field = &self.fields()[index];
34		reifydb_assertions! {
35			assert!(
36				row.len() >= self.total_static_size(),
37				"row/shape size mismatch: row.len()={} < total_static_size()={}",
38				row.len(),
39				self.total_static_size()
40			);
41			assert_eq!(*field.constraint.get_type().inner_type(), ValueType::Blob);
42		}
43
44		let ref_slice = &row[field.offset as usize..field.offset as usize + 8];
45		let offset = u32::from_le_bytes([ref_slice[0], ref_slice[1], ref_slice[2], ref_slice[3]]) as usize;
46		let length = u32::from_le_bytes([ref_slice[4], ref_slice[5], ref_slice[6], ref_slice[7]]) as usize;
47
48		let dynamic_start = self.dynamic_section_start();
49		let blob_start = dynamic_start + offset;
50		&row[blob_start..blob_start + length]
51	}
52}