use crate::laszip::sequential::appender::prepare_compressor_for_appending;
use crate::laszip::ChunkTable;
use crate::{LazVlr, ParLasZipCompressor};
use rayon::iter::IntoParallelIterator;
use std::io::{Read, Seek, SeekFrom, Write};
pub struct ParLasZipAppender<W> {
saved_chunk_table: ChunkTable,
compressor: ParLasZipCompressor<W>,
}
impl<W> ParLasZipAppender<W>
where
W: Read + Write + Seek + Send + Sync,
{
pub fn new(data: W, vlr: LazVlr, point_count: u64) -> crate::Result<Self> {
let (compressor, chunk_table) = prepare_compressor_for_appending(
data,
vlr,
point_count,
ParLasZipCompressor::new,
ParLasZipCompressor::get_mut,
)?;
Ok(Self {
saved_chunk_table: chunk_table,
compressor,
})
}
pub fn done(&mut self) -> crate::Result<()> {
self.compressor.done()?;
let pos = self.compressor.chunk_table_position_offset() as u64;
self.compressor.get_mut().seek(SeekFrom::Start(pos))?;
let (_, chunk_table_pos) = ChunkTable::read_offset(self.compressor.get_mut())?
.expect("Somehow, the chunk table was not written");
self.saved_chunk_table.extend(self.compressor.chunk_table());
let write_point_count = self.compressor.vlr().uses_variable_size_chunks();
let dest = self.compressor.get_mut();
dest.seek(SeekFrom::Start(chunk_table_pos))?;
self.saved_chunk_table.write(dest, write_point_count)?;
Ok(())
}
pub fn get_mut(&mut self) -> &mut W {
self.compressor.get_mut()
}
pub fn get(&self) -> &W {
self.compressor.get()
}
pub fn into_inner(self) -> W {
self.compressor.into_inner()
}
}
impl<W> ParLasZipAppender<W>
where
W: Write + Seek + Send + Sync,
{
pub fn compress_many(&mut self, points: &[u8]) -> std::io::Result<()> {
self.compressor.compress_many(points)
}
pub fn compress_chunks<Chunks, Item>(&mut self, chunks: Chunks) -> std::io::Result<()>
where
Item: AsRef<[u8]> + Send,
Chunks: IntoParallelIterator<Item = Item>,
{
self.compressor.compress_chunks(chunks)
}
}