diff options
| author | metamuffin <metamuffin@disroot.org> | 2026-02-16 19:29:28 +0100 |
|---|---|---|
| committer | metamuffin <metamuffin@disroot.org> | 2026-02-16 19:29:28 +0100 |
| commit | f508ec842da225f4946c40953bf24b424f52512d (patch) | |
| tree | 983bd1f7c36a4331498735d6b2ec32ae4c8d0475 /common/object | |
| parent | be4af57d75cc1e233b4714b18198fb7bde49464d (diff) | |
| download | jellything-f508ec842da225f4946c40953bf24b424f52512d.tar jellything-f508ec842da225f4946c40953bf24b424f52512d.tar.bz2 jellything-f508ec842da225f4946c40953bf24b424f52512d.tar.zst | |
handle unaligned vecs/slices
Diffstat (limited to 'common/object')
| -rw-r--r-- | common/object/src/buffer.rs | 44 | ||||
| -rw-r--r-- | common/object/src/lib.rs | 2 |
2 files changed, 32 insertions, 14 deletions
diff --git a/common/object/src/buffer.rs b/common/object/src/buffer.rs index f73b22e..1792d73 100644 --- a/common/object/src/buffer.rs +++ b/common/object/src/buffer.rs @@ -5,7 +5,9 @@ */ use crate::{Object, Tag, ValueStore}; -use bytemuck::try_cast_vec; +use bytemuck::{try_cast_slice, try_cast_vec}; +use log::trace; +use std::borrow::Cow; #[derive(PartialEq, Eq, Hash)] pub struct ObjectBuffer(pub Vec<u32>); @@ -32,13 +34,9 @@ impl ObjectBuffer { } else { temp.clear(); val.store_unaligned(&mut temp); - let mut pad = 0; - while temp.len() % 4 != 0 { - pad += 1; - temp.push(0); - } + let pad = pad_vec(&mut temp); offsets.push(off | pad); - values.extend(bytemuck::cast_slice(&temp)); // ok bc. temp length is a whole number of dwords + values.extend(&*slice_u8_to_u32(&temp)); } } ObjectBuffer( @@ -54,12 +52,7 @@ impl ObjectBuffer { impl From<Vec<u8>> for ObjectBuffer { fn from(value: Vec<u8>) -> Self { - ObjectBuffer(try_cast_vec(value).unwrap_or_else(|(_, v)| { - v.into_iter() - .array_chunks() - .map(u32::from_ne_bytes) - .collect() - })) + ObjectBuffer(vec_u8_to_u32(value)) } } @@ -72,3 +65,28 @@ pub(super) fn pad_vec(temp: &mut Vec<u8>) -> u32 { } pad } + +pub fn vec_u8_to_u32(value: Vec<u8>) -> Vec<u32> { + try_cast_vec(value).unwrap_or_else(|(_, v)| { + trace!("encountered unalined vec"); + v.into_iter() + .array_chunks() + .map(u32::from_ne_bytes) + .collect() + }) +} +pub fn slice_u8_to_u32<'a>(value: &'a [u8]) -> Cow<'a, [u32]> { + try_cast_slice(value) + .map(Cow::Borrowed) + .unwrap_or_else(|_| { + trace!("encountered unalined slice"); + Cow::Owned( + value + .into_iter() + .copied() + .array_chunks() + .map(u32::from_ne_bytes) + .collect(), + ) + }) +} diff --git a/common/object/src/lib.rs b/common/object/src/lib.rs index 9af4f85..771dd94 100644 --- a/common/object/src/lib.rs +++ b/common/object/src/lib.rs @@ -237,7 +237,7 @@ impl<'a> Object<'a> { val.store_unaligned(&mut temp); let pad = pad_vec(&mut temp); buf[new_offs + i] = off | pad; - buf.extend(bytemuck::cast_slice(&temp)); + buf.extend(&*slice_u8_to_u32(&temp)); } } let values_insert_size = buf.len() - values_new; |