zstd encode
This commit is contained in:
63
src/v1.rs
63
src/v1.rs
@@ -746,6 +746,7 @@ pub fn serialize<W:binrw::BinWriterExt>(block:&Block,writer:&mut W)->Result<(),B
|
||||
use std::ops::Range;
|
||||
const MAX_BLOCK_SIZE:usize=1<<18;
|
||||
const FILE_VERSION:u32=1;
|
||||
const COMPRESSION_LEVEL:i32=19;
|
||||
const EVENT_TYPES:[EventType;8]=[
|
||||
EventType::Input,
|
||||
EventType::Output,
|
||||
@@ -896,7 +897,40 @@ pub fn serialize<W:binrw::BinWriterExt>(block:&Block,writer:&mut W)->Result<(),B
|
||||
num_realtime_blocks:plan_realtime.len() as u32,
|
||||
};
|
||||
|
||||
let mut plan_order=Vec::with_capacity(plan_offline.len()+plan_realtime.len());
|
||||
fn create_block(block:&Block,plan:Plan<Range<usize>>)->Result<Vec<u8>,BinrwError>{
|
||||
let allocation_size=plan.size();
|
||||
let mut buffer=Vec::with_capacity(allocation_size);
|
||||
let mut cursor=std::io::Cursor::new(&mut buffer);
|
||||
|
||||
let block_header=plan.header();
|
||||
for (range,event_type) in plan.0.into_iter().zip(EVENT_TYPES){
|
||||
let num_events=range.len();
|
||||
if num_events==0{
|
||||
continue;
|
||||
}
|
||||
match event_type{
|
||||
EventType::Input=>block.input_events[range].write_le(&mut cursor)?,
|
||||
EventType::Output=>block.output_events[range].write_le(&mut cursor)?,
|
||||
EventType::Sound=>block.sound_events[range].write_le(&mut cursor)?,
|
||||
EventType::World=>block.world_events[range].write_le(&mut cursor)?,
|
||||
EventType::Gravity=>block.gravity_events[range].write_le(&mut cursor)?,
|
||||
EventType::Run=>block.run_events[range].write_le(&mut cursor)?,
|
||||
EventType::Camera=>block.camera_events[range].write_le(&mut cursor)?,
|
||||
EventType::Setting=>block.setting_events[range].write_le(&mut cursor)?,
|
||||
}
|
||||
}
|
||||
|
||||
// Allocate way too much space, whatever.
|
||||
let mut output=Vec::with_capacity(allocation_size);
|
||||
// Block includes header uncompressed, since the header unambiguously
|
||||
// determines the size of the output data and that may be useful.
|
||||
block_header.write_le(&mut std::io::Cursor::new(&mut output))?;
|
||||
zstd::stream::copy_encode(buffer.as_slice(),&mut output,COMPRESSION_LEVEL)?;
|
||||
|
||||
Ok(output)
|
||||
}
|
||||
|
||||
let mut blocks=Vec::with_capacity(plan_offline.len()+plan_realtime.len());
|
||||
let mut block_positions=Vec::with_capacity(file_header.block_position_count() as usize);
|
||||
// Fill the timelines with dummy values, we don't know the block ids yet.
|
||||
// This can be done with Vec::spare_capacity_mut and unsafe, but whatever.
|
||||
@@ -910,7 +944,9 @@ pub fn serialize<W:binrw::BinWriterExt>(block:&Block,writer:&mut W)->Result<(),B
|
||||
let mut block_id=0;
|
||||
let mut push_block=|timeline:&mut Vec<Timed<BlockId>>,planned:PlannedBlock|{
|
||||
block_positions.push(BlockPosition(position));
|
||||
position+=planned.plan.size() as u32;
|
||||
let block=create_block(block,planned.plan).unwrap();
|
||||
position+=block.len() as u32;
|
||||
blocks.push(block);
|
||||
|
||||
// write the block id to the correct index
|
||||
timeline[planned.index]=Timed{
|
||||
@@ -918,8 +954,6 @@ pub fn serialize<W:binrw::BinWriterExt>(block:&Block,writer:&mut W)->Result<(),B
|
||||
event:BlockId(block_id),
|
||||
};
|
||||
block_id+=1;
|
||||
|
||||
plan_order.push(planned.plan);
|
||||
};
|
||||
// the first block in the file is an offline block to
|
||||
// initialize the state of things like the current style
|
||||
@@ -960,25 +994,8 @@ pub fn serialize<W:binrw::BinWriterExt>(block:&Block,writer:&mut W)->Result<(),B
|
||||
use binrw::BinWrite;
|
||||
file_header.write_le(writer)?;
|
||||
block_timelines.write_le(writer)?;
|
||||
for plan in plan_order{
|
||||
let block_header=plan.header();
|
||||
block_header.write_le(writer)?;
|
||||
for (range,event_type) in plan.0.into_iter().zip(EVENT_TYPES){
|
||||
let num_events=range.len();
|
||||
if num_events==0{
|
||||
continue;
|
||||
}
|
||||
match event_type{
|
||||
EventType::Input=>block.input_events[range].write_le(writer)?,
|
||||
EventType::Output=>block.output_events[range].write_le(writer)?,
|
||||
EventType::Sound=>block.sound_events[range].write_le(writer)?,
|
||||
EventType::World=>block.world_events[range].write_le(writer)?,
|
||||
EventType::Gravity=>block.gravity_events[range].write_le(writer)?,
|
||||
EventType::Run=>block.run_events[range].write_le(writer)?,
|
||||
EventType::Camera=>block.camera_events[range].write_le(writer)?,
|
||||
EventType::Setting=>block.setting_events[range].write_le(writer)?,
|
||||
}
|
||||
}
|
||||
for block in blocks{
|
||||
writer.write_all(&block)?;
|
||||
}
|
||||
|
||||
Ok(())
|
||||
|
||||
Reference in New Issue
Block a user