diff options
Diffstat (limited to 'common/object/src/buffer.rs')
| -rw-r--r-- | common/object/src/buffer.rs | 76 |
1 files changed, 19 insertions, 57 deletions
diff --git a/common/object/src/buffer.rs b/common/object/src/buffer.rs index 1f8cec6..4d3af34 100644 --- a/common/object/src/buffer.rs +++ b/common/object/src/buffer.rs @@ -4,56 +4,12 @@ Copyright (C) 2026 metamuffin <metamuffin.org> */ -use crate::{Object, Tag, TypedTag, ValueStore}; +use crate::{Object, Tag, TypedTag, ValueMarker, value::ValueSer}; use bytemuck::{try_cast_slice, try_cast_vec}; +use core::marker::Sized; use log::trace; use std::borrow::Cow; -#[derive(PartialEq, Eq, Hash)] -pub struct ObjectBuffer(pub Vec<u32>); - -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 to_bytes(self) -> Vec<u8> { - self.0.into_iter().flat_map(u32::to_le_bytes).collect() - } - 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); - let ty = val.get_type(); - let off = (values.len() as u32) << 5 | (ty as u32) << 2; - if ty.is_aligned() { - offsets.push(off); - val.store_aligned(&mut values); - } else { - temp.clear(); - val.store_unaligned(&mut temp); - let pad = pad_vec(&mut temp); - offsets.push(off | pad); - values.extend(&*slice_u8_to_u32(&temp)); - } - } - ObjectBuffer( - [tags.len() as u32] - .into_iter() - .chain(tags) - .chain(offsets) - .chain(values) - .collect(), - ) - } -} - pub type OBB = ObjectBufferBuilder; #[derive(Default)] @@ -62,10 +18,9 @@ impl ObjectBufferBuilder { pub fn new() -> Self { Self::default() } - 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() { + pub fn push<'a, T: ValueMarker<'a> + ?Sized>(&mut self, tag: TypedTag<T>, value: T::Inner) { + let tyb = (T::Inner::TYPE as u32) << 2; + if T::Inner::TYPE.is_aligned() { let mut buf = Vec::new(); value.store_aligned(&mut buf); self.0.push((tag.0, tyb, buf)); @@ -76,11 +31,15 @@ impl ObjectBufferBuilder { self.0.push((tag.0, tyb | pad, vec_u8_to_u32(buf))); } } - pub fn with<T: ValueStore>(mut self, tag: TypedTag<T>, value: T) -> Self { + pub fn with<'a, T: ValueMarker<'a> + ?Sized>( + mut self, + tag: TypedTag<T>, + value: T::Inner, + ) -> Self { self.push(tag, value); self } - pub fn finish(mut self) -> ObjectBuffer { + pub fn finish(mut self) -> Box<Object> { let mut tags = Vec::new(); let mut offsets = Vec::new(); let mut values = Vec::new(); @@ -91,7 +50,7 @@ impl ObjectBufferBuilder { offsets.push(off); values.extend(buf); } - ObjectBuffer( + vec_to_ob( [tags.len() as u32] .into_iter() .chain(tags) @@ -102,10 +61,13 @@ impl ObjectBufferBuilder { } } -impl From<Vec<u8>> for ObjectBuffer { - fn from(value: Vec<u8>) -> Self { - ObjectBuffer(vec_u8_to_u32(value)) - } +pub fn vec_to_ob(v: Vec<u32>) -> Box<Object> { + //? safe way to do this? + unsafe { std::mem::transmute(v.into_boxed_slice()) } +} +pub const fn slice_to_ob<'a>(v: &'a [u32]) -> &'a Object { + //? safe way to do this? + unsafe { std::mem::transmute(v) } } #[inline] |