use blte::{BLTEStream, CompressionMode, create_streaming_reader};
use std::io::{Cursor, Read, Write};
fn create_sample_blte_data() -> Vec<u8> {
let mut blte_data = Vec::new();
blte_data.extend_from_slice(b"BLTE");
blte_data.extend_from_slice(&0u32.to_be_bytes());
blte_data.push(CompressionMode::None.as_byte());
blte_data.extend_from_slice(
b"This is a sample BLTE file content that will be streamed chunk by chunk!",
);
blte_data
}
fn create_multi_chunk_blte_data() -> Vec<u8> {
use flate2::{Compression, write::ZlibEncoder};
let chunk1_data = b"First chunk: ";
let chunk2_data = b"Second chunk with more data to make compression worthwhile!";
let mut encoder1 = ZlibEncoder::new(Vec::new(), Compression::default());
encoder1.write_all(chunk1_data).unwrap();
let compressed1 = encoder1.finish().unwrap();
let mut encoder2 = ZlibEncoder::new(Vec::new(), Compression::default());
encoder2.write_all(chunk2_data).unwrap();
let compressed2 = encoder2.finish().unwrap();
let mut chunk1_full = Vec::new();
chunk1_full.push(CompressionMode::ZLib.as_byte());
chunk1_full.extend_from_slice(&compressed1);
let mut chunk2_full = Vec::new();
chunk2_full.push(CompressionMode::ZLib.as_byte());
chunk2_full.extend_from_slice(&compressed2);
let header_size = 8 + 1 + 3 + 2 * 24;
let mut blte_data = Vec::new();
blte_data.extend_from_slice(b"BLTE");
blte_data.extend_from_slice(&(header_size as u32).to_be_bytes());
blte_data.push(0x0F); blte_data.extend_from_slice(&[0x00, 0x00, 0x02]);
blte_data.extend_from_slice(&(chunk1_full.len() as u32).to_be_bytes());
blte_data.extend_from_slice(&(chunk1_data.len() as u32).to_be_bytes());
blte_data.extend_from_slice(&[0; 16]);
blte_data.extend_from_slice(&(chunk2_full.len() as u32).to_be_bytes());
blte_data.extend_from_slice(&(chunk2_data.len() as u32).to_be_bytes());
blte_data.extend_from_slice(&[0; 16]);
blte_data.extend_from_slice(&chunk1_full);
blte_data.extend_from_slice(&chunk2_full);
blte_data
}
fn main() -> Result<(), Box<dyn std::error::Error>> {
println!("BLTE Streaming Decompression Example");
println!("====================================");
println!("\n1. Single Chunk Streaming:");
let simple_data = create_sample_blte_data();
println!(" Original BLTE data size: {} bytes", simple_data.len());
let cursor = Cursor::new(simple_data);
let mut stream = BLTEStream::new(cursor, None)?;
println!(" Stream created with {} chunks", stream.chunk_count());
let mut decompressed = String::new();
stream.read_to_string(&mut decompressed)?;
println!(" Decompressed content: \"{decompressed}\"");
println!(" Decompressed size: {} bytes", decompressed.len());
println!("\n2. Multi-Chunk Streaming:");
let multi_data = create_multi_chunk_blte_data();
println!(" Original BLTE data size: {} bytes", multi_data.len());
let cursor = Cursor::new(multi_data);
let mut multi_stream = BLTEStream::new(cursor, None)?;
println!(
" Stream created with {} chunks",
multi_stream.chunk_count()
);
let mut multi_decompressed = String::new();
multi_stream.read_to_string(&mut multi_decompressed)?;
println!(" Decompressed content: \"{multi_decompressed}\"");
println!(" Decompressed size: {} bytes", multi_decompressed.len());
println!("\n3. Small Buffer Streaming (simulating large file processing):");
let buffer_data = create_multi_chunk_blte_data();
let cursor = Cursor::new(buffer_data);
let mut buffer_stream = BLTEStream::new(cursor, None)?;
let mut buffer = [0u8; 8]; let mut total_bytes = 0;
let mut chunks_read = 0;
println!(" Reading in 8-byte chunks:");
loop {
let bytes_read = buffer_stream.read(&mut buffer)?;
if bytes_read == 0 {
break; }
chunks_read += 1;
total_bytes += bytes_read;
let chunk_str = String::from_utf8_lossy(&buffer[..bytes_read]);
println!(" Chunk {chunks_read}: {bytes_read} bytes -> \"{chunk_str}\"");
}
println!(" Total bytes read: {total_bytes}");
println!(" Total read operations: {chunks_read}");
println!("\n4. Using convenience function:");
let convenience_data = create_sample_blte_data();
let cursor = Cursor::new(convenience_data);
let mut convenience_stream = create_streaming_reader(cursor, None)?;
let mut convenience_result = String::new();
convenience_stream.read_to_string(&mut convenience_result)?;
println!(" Result: \"{convenience_result}\"");
println!("\n✅ All streaming examples completed successfully!");
println!("\nStreaming benefits:");
println!("• Memory efficient for large BLTE files");
println!("• Can process data as it becomes available");
println!("• Supports all BLTE compression modes");
println!("• Compatible with standard Read trait");
Ok(())
}