diff options
| author | metamuffin <metamuffin@disroot.org> | 2026-02-18 20:42:16 +0100 |
|---|---|---|
| committer | metamuffin <metamuffin@disroot.org> | 2026-02-18 20:42:16 +0100 |
| commit | e1b67c885d5789268cec53ac68479a329fba9c8f (patch) | |
| tree | f6b842854fb48553f42f03fe4ef3b4b0d17ad579 /common | |
| parent | 848cd3e478d77daf75076e5ee075fb4f76304baa (diff) | |
| download | jellything-e1b67c885d5789268cec53ac68479a329fba9c8f.tar jellything-e1b67c885d5789268cec53ac68479a329fba9c8f.tar.bz2 jellything-e1b67c885d5789268cec53ac68479a329fba9c8f.tar.zst | |
ObjectBufferBuilder
Diffstat (limited to 'common')
| -rw-r--r-- | common/object/src/buffer.rs | 41 |
1 files changed, 40 insertions, 1 deletions
diff --git a/common/object/src/buffer.rs b/common/object/src/buffer.rs index 829cade..703e203 100644 --- a/common/object/src/buffer.rs +++ b/common/object/src/buffer.rs @@ -4,7 +4,7 @@ Copyright (C) 2026 metamuffin <metamuffin.org> */ -use crate::{Object, Tag, ValueStore}; +use crate::{Object, Tag, TypedTag, ValueStore}; use bytemuck::{try_cast_slice, try_cast_vec}; use log::trace; use std::borrow::Cow; @@ -54,6 +54,45 @@ impl ObjectBuffer { } } +#[derive(Default)] +pub struct ObjectBufferBuilder(Vec<(Tag, u32, Vec<u32>)>); +impl ObjectBufferBuilder { + pub fn push<T: ValueStore>(&mut self, tag: TypedTag<T>, value: T) { + let ty = value.get_type(); + let tyb = (ty as u32) << 2; + if ty.is_aligned() { + let mut buf = Vec::new(); + value.store_aligned(&mut buf); + self.0.push((tag.0, tyb, buf)); + } else { + let mut buf = Vec::new(); + value.store_unaligned(&mut buf); + let pad = pad_vec(&mut buf); + self.0.push((tag.0, tyb | pad, vec_u8_to_u32(buf))); + } + } + pub fn finish(mut self) -> ObjectBuffer { + let mut tags = Vec::new(); + let mut offsets = Vec::new(); + let mut values = Vec::new(); + self.0.sort_by_key(|(t, _, _)| t.0); + for (tag, mut off, buf) in self.0 { + tags.push(tag.0); + off |= (values.len() as u32) << 5; + offsets.push(off); + values.extend(buf); + } + ObjectBuffer( + [tags.len() as u32] + .into_iter() + .chain(tags) + .chain(offsets) + .chain(values) + .collect(), + ) + } +} + impl From<Vec<u8>> for ObjectBuffer { fn from(value: Vec<u8>) -> Self { ObjectBuffer(vec_u8_to_u32(value)) |