aboutsummaryrefslogtreecommitdiff
path: root/common/object/src/buffer.rs
diff options
context:
space:
mode:
Diffstat (limited to 'common/object/src/buffer.rs')
-rw-r--r--common/object/src/buffer.rs76
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]