diff options
Diffstat (limited to 'common/object/src/lib.rs')
| -rw-r--r-- | common/object/src/lib.rs | 64 |
1 files changed, 49 insertions, 15 deletions
diff --git a/common/object/src/lib.rs b/common/object/src/lib.rs index 771dd94..bd00639 100644 --- a/common/object/src/lib.rs +++ b/common/object/src/lib.rs @@ -6,7 +6,7 @@ #![feature(iter_array_chunks)] mod buffer; -pub mod inspect; +pub mod debug; #[cfg(feature = "json")] pub mod json; mod path; @@ -20,14 +20,30 @@ pub use path::*; pub use registry::*; pub use value::*; -use std::{collections::BTreeSet, hash::Hash, marker::PhantomData}; +use std::{collections::BTreeSet, fmt::Display, hash::Hash, marker::PhantomData}; #[repr(transparent)] -#[derive(Debug, Clone, Copy, PartialEq, Eq, PartialOrd, Ord, Hash)] +#[derive(Clone, Copy, PartialEq, Eq, PartialOrd, Ord, Hash)] pub struct Tag(pub u32); -#[derive(Debug, PartialEq, Eq, PartialOrd, Ord)] +impl Tag { + pub const fn new(fourcc: &[u8; 4]) -> Self { + Self(u32::from_be_bytes(*fourcc)) + } +} +impl Display for Tag { + fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result { + f.write_str(str::from_utf8(&self.0.to_be_bytes()).unwrap()) + } +} + +#[derive(PartialEq, Eq, PartialOrd, Ord)] pub struct TypedTag<T>(pub Tag, pub PhantomData<T>); +impl<T> Display for TypedTag<T> { + fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result { + self.0.fmt(f) + } +} impl<T> Clone for TypedTag<T> { fn clone(&self) -> Self { @@ -36,7 +52,7 @@ impl<T> Clone for TypedTag<T> { } impl<T> Copy for TypedTag<T> {} -#[derive(Debug, Clone, Copy, Hash, PartialEq, Eq)] +#[derive(Clone, Copy, Hash, PartialEq, Eq)] pub struct Object<'a> { tags: &'a [u32], offsets: &'a [u32], @@ -89,33 +105,50 @@ impl<'a> Object<'a> { fn offset(&self, i: usize) -> usize { self.offsets .get(i) - .map(|&v| v >> 2) + .map(|&v| v >> 5) .unwrap_or(self.values.len() as u32) as usize } + fn offset_type(&self, i: usize) -> ValueType { + let raw = (self.offsets[i] >> 2) & 0b111; + ValueType::from_num(raw) + } + fn size(&self, i: usize) -> u32 { + let start_raw = self.offsets[i]; + let end_raw = self + .offsets + .get(i + 1) + .copied() + .unwrap_or((self.values.len() as u32) << 5); + + let u32_len = (end_raw >> 5) - (start_raw >> 5); + let padding = start_raw & 0b11; + u32_len * 4 - padding + } fn get_aligned(&self, index: usize) -> Option<&'a [u32]> { let start_raw = self.offsets[index]; let end_raw = self .offsets .get(index + 1) .copied() - .unwrap_or((self.values.len() as u32) << 2); + .unwrap_or((self.values.len() as u32) << 5); - let start = start_raw >> 2; - let end = end_raw >> 2; + let start = start_raw >> 5; + let end = end_raw >> 5; Some(&self.values[start as usize..end as usize]) } + fn get_unaligned(&self, index: usize) -> Option<&'a [u8]> { let start_raw = self.offsets[index]; let end_raw = self .offsets .get(index + 1) .copied() - .unwrap_or((self.values.len() as u32) << 2); + .unwrap_or((self.values.len() as u32) << 5); - let start = (start_raw >> 2) * 4; + let start = (start_raw >> 5) * 4; let padding = start_raw & 0b11; - let end = (end_raw >> 2) * 4 - padding; + let end = (end_raw >> 5) * 4 - padding; let values_u8: &[u8] = bytemuck::cast_slice(self.values); Some(&values_u8[start as usize..end as usize]) @@ -228,8 +261,9 @@ impl<'a> Object<'a> { let mut temp = Vec::new(); let values_new = buf.len(); for (i, val) in values.iter().enumerate() { - let off = (buf.len() as u32 - values_start) << 2; - if val.is_aligned() { + let ty = val.get_type(); + let off = (buf.len() as u32 - values_start) << 5 | (ty as u32) << 2; + if ty.is_aligned() { buf[new_offs + i] = off; val.store_aligned(&mut buf); } else { @@ -242,7 +276,7 @@ impl<'a> Object<'a> { } let values_insert_size = buf.len() - values_new; let values_cut_size = values_suffix - values_prefix; - let suffix_offset = (values_insert_size as i32 - values_cut_size as i32) * 4; + let suffix_offset = (values_insert_size as i32 - values_cut_size as i32) << 5; if suffix_offset != 0 { buf[suffix_offs..suffix_end] .iter_mut() |