coven_format/
sealed_stream.rs1use crate::chunks::CHUNK_SIZE;
4use crate::error::{require, Error, Rule};
5use crate::sealed;
6use coven_crypto::{Signature, SEALED_OBJECT_CHUNK_OVERHEAD};
7
8pub struct StreamObjectLayout {
12 index: u64,
13 partial: bool,
14}
15impl Default for StreamObjectLayout {
16 fn default() -> Self {
17 Self::new()
18 }
19}
20impl StreamObjectLayout {
21 pub fn new() -> Self {
23 Self { index: 0, partial: false }
24 }
25
26 pub fn index(&self) -> u64 {
28 self.index
29 }
30
31 pub fn chunk_length(&self, prefix: &[u8]) -> Result<usize, Error> {
33 require(!self.partial, "chunk after stream's final partial chunk", Rule::Chunk)?;
34 sealed::chunk_length(prefix, CHUNK_SIZE)
35 }
36
37 pub fn encode_chunk(&mut self, bytes: &[u8]) -> Result<Vec<u8>, Error> {
39 require(
40 !self.partial
41 && (SEALED_OBJECT_CHUNK_OVERHEAD + 1..=CHUNK_SIZE + SEALED_OBJECT_CHUNK_OVERHEAD)
42 .contains(&bytes.len()),
43 "stream chunk length",
44 Rule::Chunk,
45 )?;
46 let piece = sealed::encode_chunk(bytes)?;
47 self.advance(bytes.len())?;
48 Ok(piece)
49 }
50
51 pub fn decode_chunk<'a>(&mut self, piece: &'a [u8]) -> Result<&'a [u8], Error> {
53 self.chunk_length(piece)?;
54 let bytes = sealed::chunk(piece, CHUNK_SIZE)?;
55 self.advance(bytes.len())?;
56 Ok(bytes)
57 }
58
59 pub fn read_signature(self, bytes: &[u8]) -> Result<Signature, Error> {
63 require(self.index > 0, "stream chunks", Rule::Required)?;
64 sealed::signature(bytes)
65 }
66
67 fn advance(&mut self, length: usize) -> Result<(), Error> {
68 self.index = self
69 .index
70 .checked_add(1)
71 .ok_or(Error::Invalid { field: "stream chunk index", rule: Rule::Chunk })?;
72 self.partial = length < CHUNK_SIZE + SEALED_OBJECT_CHUNK_OVERHEAD;
73 Ok(())
74 }
75}
76
77pub fn plaintext_length(sealed: u64) -> Result<u64, Error> {
79 let overhead = crate::STORED_CHUNK_OVERHEAD as u64;
80 let full = CHUNK_SIZE as u64 + overhead;
81 require(sealed > 0, "stream chunks", Rule::Required)?;
82 let chunks = sealed.div_ceil(full);
83 require(sealed - (chunks - 1) * full > overhead, "stream final chunk", Rule::Chunk)?;
84 Ok(sealed - chunks * overhead)
85}