From ffbdb9ce397a6408d5a91cbdcbaf4e13b0c3ba0b Mon Sep 17 00:00:00 2001 From: metamuffin Date: Tue, 6 Jan 2026 14:56:20 +0100 Subject: Multi fields; object buffer constructor; unit tests --- common/object/src/buffer.rs | 50 +++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 50 insertions(+) create mode 100644 common/object/src/buffer.rs (limited to 'common/object/src/buffer.rs') diff --git a/common/object/src/buffer.rs b/common/object/src/buffer.rs new file mode 100644 index 0000000..56b8caf --- /dev/null +++ b/common/object/src/buffer.rs @@ -0,0 +1,50 @@ +/* + This file is part of jellything (https://codeberg.org/metamuffin/jellything) + which is licensed under the GNU Affero General Public License (version 3); see /COPYING. + Copyright (C) 2026 metamuffin +*/ + +use crate::{Object, Tag, ValueStore}; + +pub struct ObjectBuffer(pub Vec); + +impl ObjectBuffer { + pub fn empty() -> Self { + Self(vec![0]) + } + pub fn as_object<'a>(&'a self) -> Object<'a> { + Object::load(&self.0).unwrap() + } + pub fn new(fields: &mut [(Tag, &dyn ValueStore)]) -> ObjectBuffer { + let mut tags = Vec::new(); + let mut offsets = Vec::new(); + let mut values = Vec::new(); + fields.sort_by_key(|(t, _)| t.0); + let mut temp = Vec::new(); + for (tag, val) in fields { + tags.push(tag.0); + if val.is_aligned() { + offsets.push((values.len() as u32) << 2); + val.store_aligned(&mut values); + } else { + temp.clear(); + val.store_unaligned(&mut temp); + let mut pad = 0; + while temp.len() % 4 != 0 { + pad += 1; + temp.push(0); + } + offsets.push(((values.len() as u32) << 2) | pad); + values.extend(bytemuck::cast_slice(&temp)); // ok bc. temp length is a whole number of dwords + } + } + ObjectBuffer( + [tags.len() as u32] + .into_iter() + .chain(tags) + .chain(offsets) + .chain(values) + .collect(), + ) + } +} -- cgit v1.3