|
42 | 42 |
|
43 | 43 | pub use hybrid_array as array; |
44 | 44 |
|
45 | | -use array::{ |
46 | | - Array, ArraySize, |
47 | | - typenum::{Add1, B1}, |
48 | | -}; |
49 | | -use core::{fmt, mem::MaybeUninit, ops::Add, ptr, slice}; |
| 45 | +use array::{Array, ArraySize, typenum::Sum}; |
| 46 | +use core::{fmt, mem::MaybeUninit, ptr, slice}; |
50 | 47 |
|
51 | 48 | #[cfg(feature = "zeroize")] |
52 | 49 | use zeroize::{Zeroize, ZeroizeOnDrop}; |
@@ -314,6 +311,47 @@ impl<BS: ArraySize, K: BufferKind> BlockBuffer<BS, K> { |
314 | 311 | } |
315 | 312 | } |
316 | 313 |
|
| 314 | +/// Size of serialized `BlockBuffer` in bytes. |
| 315 | +pub type SerializedBufferSize<BS, K> = Sum<BS, <K as sealed::Sealed>::Overhead>; |
| 316 | +/// `BlockBuffer` serialized as a byte array. |
| 317 | +pub type SerializedBuffer<BS, K> = Array<u8, SerializedBufferSize<BS, K>>; |
| 318 | + |
| 319 | +impl<BS: ArraySize, K: BufferKind> BlockBuffer<BS, K> |
| 320 | +where |
| 321 | + BS: core::ops::Add<K::Overhead>, |
| 322 | + Sum<BS, K::Overhead>: ArraySize, |
| 323 | +{ |
| 324 | + /// Serialize buffer into a byte array. |
| 325 | + pub fn serialize(&self) -> SerializedBuffer<BS, K> { |
| 326 | + let mut buf = SerializedBuffer::<BS, K>::default(); |
| 327 | + let data = self.get_data(); |
| 328 | + let (pos, block) = buf.split_at_mut(1); |
| 329 | + pos[0] = u8::try_from(data.len()).expect("buffer size is smaller than 256"); |
| 330 | + block[..data.len()].copy_from_slice(data); |
| 331 | + buf |
| 332 | + } |
| 333 | + |
| 334 | + /// Deserialize buffer from a byte array. |
| 335 | + pub fn deserialize(buf: &SerializedBuffer<BS, K>) -> Result<Self, Error> { |
| 336 | + let (pos, block) = buf.split_at(1); |
| 337 | + let pos = usize::from(pos[0]); |
| 338 | + |
| 339 | + if !<K as sealed::Sealed>::invariant(pos, BS::USIZE) { |
| 340 | + return Err(Error); |
| 341 | + } |
| 342 | + |
| 343 | + let (data, tail) = block.split_at(pos); |
| 344 | + |
| 345 | + if tail.iter().any(|&b| b != 0) { |
| 346 | + return Err(Error); |
| 347 | + } |
| 348 | + |
| 349 | + let mut res = Self::default(); |
| 350 | + unsafe { res.set_data_unchecked(data) }; |
| 351 | + Ok(res) |
| 352 | + } |
| 353 | +} |
| 354 | + |
317 | 355 | impl<BS: ArraySize> BlockBuffer<BS, Eager> { |
318 | 356 | /// Compress remaining data after padding it with `delim`, zeros and |
319 | 357 | /// the `suffix` bytes. If there is not enough unused space, `compress` |
@@ -368,69 +406,6 @@ impl<BS: ArraySize> BlockBuffer<BS, Eager> { |
368 | 406 | pub fn len128_padding_be(&mut self, data_len: u128, compress: impl FnMut(&Array<u8, BS>)) { |
369 | 407 | self.digest_pad(0x80, &data_len.to_be_bytes(), compress); |
370 | 408 | } |
371 | | - |
372 | | - /// Serialize buffer into a byte array. |
373 | | - #[inline] |
374 | | - pub fn serialize(&self) -> Array<u8, BS> { |
375 | | - let mut res = Array::<u8, BS>::default(); |
376 | | - let data = self.get_data(); |
377 | | - res[..data.len()].copy_from_slice(data); |
378 | | - res[BS::USIZE - 1] = data.len() as u8; |
379 | | - res |
380 | | - } |
381 | | - |
382 | | - /// Deserialize buffer from a byte array. |
383 | | - #[inline] |
384 | | - pub fn deserialize(buffer: &Array<u8, BS>) -> Result<Self, Error> { |
385 | | - let pos = buffer[BS::USIZE - 1] as usize; |
386 | | - if !<Eager as sealed::Sealed>::invariant(pos, BS::USIZE) { |
387 | | - return Err(Error); |
388 | | - } |
389 | | - if buffer[pos..BS::USIZE - 1].iter().any(|&b| b != 0) { |
390 | | - return Err(Error); |
391 | | - } |
392 | | - Ok(Self { |
393 | | - buffer: MaybeUninit::new(buffer.clone()), |
394 | | - pos: Default::default(), |
395 | | - }) |
396 | | - } |
397 | | -} |
398 | | - |
399 | | -impl<BS: ArraySize> BlockBuffer<BS, Lazy> { |
400 | | - /// Serialize buffer into a byte array. |
401 | | - #[inline] |
402 | | - pub fn serialize(&self) -> Array<u8, Add1<BS>> |
403 | | - where |
404 | | - BS: Add<B1>, |
405 | | - Add1<BS>: ArraySize, |
406 | | - { |
407 | | - let mut res = Array::<u8, Add1<BS>>::default(); |
408 | | - res[0] = self.pos; |
409 | | - let data = self.get_data(); |
410 | | - res[1..][..data.len()].copy_from_slice(data); |
411 | | - res |
412 | | - } |
413 | | - |
414 | | - /// Deserialize buffer from a byte array. |
415 | | - #[inline] |
416 | | - pub fn deserialize(buffer: &Array<u8, Add1<BS>>) -> Result<Self, Error> |
417 | | - where |
418 | | - BS: Add<B1>, |
419 | | - Add1<BS>: ArraySize, |
420 | | - { |
421 | | - let pos = buffer[0]; |
422 | | - if !<Lazy as sealed::Sealed>::invariant(pos as usize, BS::USIZE) { |
423 | | - return Err(Error); |
424 | | - } |
425 | | - if buffer[1..][pos as usize..].iter().any(|&b| b != 0) { |
426 | | - return Err(Error); |
427 | | - } |
428 | | - let buf = Array::try_from(&buffer[1..]).expect("slice has correct length"); |
429 | | - Ok(Self { |
430 | | - buffer: MaybeUninit::new(buf), |
431 | | - pos, |
432 | | - }) |
433 | | - } |
434 | 409 | } |
435 | 410 |
|
436 | 411 | #[cfg(feature = "zeroize")] |
|
0 commit comments