Skip to content

Commit

Permalink
feat: add BocHeader::encode_to_writer
Browse files Browse the repository at this point in the history
  • Loading branch information
Rexagon committed Sep 30, 2024
1 parent 42d60f5 commit ea8ef5e
Showing 1 changed file with 43 additions and 0 deletions.
43 changes: 43 additions & 0 deletions src/boc/ser.rs
Original file line number Diff line number Diff line change
Expand Up @@ -117,6 +117,49 @@ where
);
}

/// Writes cell trees into the writer.
///
/// NOTE: Use [`BocHeader::encode`] when possible since it's faster.
pub fn encode_to_writer<W: std::io::Write>(&self, mut writer: W) -> std::io::Result<()> {
const CELLS_CHUNK_SIZE: usize = 1000;
const P95_CELL_SIZE: usize = 128;

let mut crc = self.include_crc.then_some(0u32);
let mut total_size = 0;

let mut reset_chunk = |chunk: &mut Vec<u8>| {
if let Some(crc) = &mut crc {
*crc = crc32c::crc32c_append(*crc, chunk);
}
total_size += chunk.len() as u64;
chunk.clear();
};

let mut chunk = Vec::new();

// Write header
let header = self.encode_header(&mut chunk);
ok!(writer.write_all(&chunk));
reset_chunk(&mut chunk);

// Write cells
for cells in self.rev_cells.rchunks(CELLS_CHUNK_SIZE) {
chunk.reserve(cells.len() * P95_CELL_SIZE);
self.encode_cells_chunk(cells, header.ref_size, &mut chunk);
ok!(writer.write_all(&chunk));
reset_chunk(&mut chunk);
}

debug_assert!(chunk.is_empty());

if let Some(crc) = crc {
ok!(writer.write_all(&crc.to_le_bytes()));
}

debug_assert_eq!(total_size, header.total_size);
Ok(())
}

/// Encodes cell trees into bytes.
/// Uses `rayon` under the hood.
#[cfg(feature = "rayon")]
Expand Down

0 comments on commit ea8ef5e

Please sign in to comment.