use std::io::Write as _;
use zip::write::{SimpleFileOptions, ZipWriter};
use zip::CompressionMethod;
pub const CHUNK_SIZE: usize = 512;
const STREAM_ARN: &str = "aff4://issen-test-stream";
const MAP_ARN: &str = "aff4://issen-test-map";
const IMAGE_STREAM_ARN: &str = "aff4://issen-test-image-stream";
const MAP_ZIP_BASE: &str = "issen-test-map";
const IMAGE_ZIP_BASE: &str = "issen-test-image-stream";
const ZIP_BASE: &str = "issen-test-stream";
pub fn test_aff4_with_geometry(chunk_size: u64, chunks_per_segment: u64) -> Vec<u8> {
let turtle = format!(
"@prefix rdf: <http://www.w3.org/1999/02/22-rdf-syntax-ns#> .\n\
@prefix aff4: <http://aff4.org/Schema#> .\n\
<{STREAM_ARN}> rdf:type aff4:ImageStream ; \
aff4:size 512 ; \
aff4:chunkSize {chunk_size} ; \
aff4:chunksInSegment {chunks_per_segment} ; \
aff4:compressionMethod aff4:NullCompressor .\n"
);
let cursor = std::io::Cursor::new(Vec::<u8>::new());
let mut zw = ZipWriter::new(cursor);
let opts = SimpleFileOptions::default().compression_method(CompressionMethod::Stored);
zw.start_file("information.turtle", opts).expect("start turtle");
zw.write_all(turtle.as_bytes()).expect("write turtle");
zw.start_file(format!("{ZIP_BASE}/00000000").as_str(), opts)
.expect("start bevy");
zw.write_all(&[0u8; 512]).expect("write bevy");
zw.start_file(format!("{ZIP_BASE}/00000000.index").as_str(), opts)
.expect("start index");
zw.write_all(&512u32.to_le_bytes()).expect("write index");
zw.finish().expect("finish zip").into_inner()
}
pub fn test_aff4(data: &[u8]) -> Vec<u8> {
let mut chunk = vec![0u8; CHUNK_SIZE];
let n = data.len().min(CHUNK_SIZE);
chunk[..n].copy_from_slice(&data[..n]);
let turtle = format!(
"@prefix rdf: <http://www.w3.org/1999/02/22-rdf-syntax-ns#> .\n\
@prefix aff4: <http://aff4.org/Schema#> .\n\
<{STREAM_ARN}> rdf:type aff4:ImageStream ; \
aff4:size {CHUNK_SIZE} ; \
aff4:chunkSize {CHUNK_SIZE} ; \
aff4:chunksInSegment 1 ; \
aff4:compressionMethod aff4:NullCompressor .\n"
);
let cursor = std::io::Cursor::new(Vec::<u8>::new());
let mut zw = ZipWriter::new(cursor);
let opts = SimpleFileOptions::default().compression_method(CompressionMethod::Stored);
zw.start_file("information.turtle", opts).expect("start turtle");
zw.write_all(turtle.as_bytes()).expect("write turtle");
let bevy_name = format!("{ZIP_BASE}/00000000");
zw.start_file(bevy_name.as_str(), opts).expect("start bevy");
zw.write_all(&chunk).expect("write bevy");
let index_name = format!("{ZIP_BASE}/00000000.index");
zw.start_file(index_name.as_str(), opts).expect("start index");
let end_offset: u32 = CHUNK_SIZE as u32;
zw.write_all(&end_offset.to_le_bytes()).expect("write index");
zw.finish().expect("finish zip").into_inner()
}
#[cfg(test)]
pub fn test_aff4_lz4(data: &[u8]) -> Vec<u8> {
let mut chunk = vec![0u8; CHUNK_SIZE];
let n = data.len().min(CHUNK_SIZE);
chunk[..n].copy_from_slice(&data[..n]);
let mut compressed = Vec::new();
{
use std::io::Write as _;
let mut enc = lz4_flex::frame::FrameEncoder::new(&mut compressed);
enc.write_all(&chunk).expect("lz4 compress");
enc.finish().expect("lz4 finish");
}
let turtle = format!(
"@prefix rdf: <http://www.w3.org/1999/02/22-rdf-syntax-ns#> .\n\
@prefix aff4: <http://aff4.org/Schema#> .\n\
<{STREAM_ARN}> rdf:type aff4:ImageStream ; \
aff4:size {CHUNK_SIZE} ; \
aff4:chunkSize {CHUNK_SIZE} ; \
aff4:chunksInSegment 1 ; \
aff4:compressionMethod <https://github.com/lz4/lz4> .\n"
);
let cursor = std::io::Cursor::new(Vec::<u8>::new());
let mut zw = ZipWriter::new(cursor);
let opts = SimpleFileOptions::default().compression_method(CompressionMethod::Stored);
zw.start_file("information.turtle", opts).expect("start turtle");
zw.write_all(turtle.as_bytes()).expect("write turtle");
let bevy_name = format!("{ZIP_BASE}/00000000");
zw.start_file(bevy_name.as_str(), opts).expect("start bevy");
zw.write_all(&compressed).expect("write bevy");
let index_name = format!("{ZIP_BASE}/00000000.index");
zw.start_file(index_name.as_str(), opts).expect("start index");
zw.write_all(&(compressed.len() as u32).to_le_bytes()).expect("write index");
zw.finish().expect("finish zip").into_inner()
}
pub fn test_aff4_map(data: &[u8]) -> Vec<u8> {
let mut chunk = vec![0u8; CHUNK_SIZE];
let n = data.len().min(CHUNK_SIZE);
chunk[..n].copy_from_slice(&data[..n]);
let virtual_size: u64 = 1024;
let turtle = format!(
"@prefix rdf: <http://www.w3.org/1999/02/22-rdf-syntax-ns#> .\n\
@prefix aff4: <http://aff4.org/Schema#> .\n\
<{IMAGE_STREAM_ARN}> rdf:type aff4:ImageStream ; \
aff4:size {CHUNK_SIZE} ; \
aff4:chunkSize {CHUNK_SIZE} ; \
aff4:chunksInSegment 1 ; \
aff4:compressionMethod aff4:NullCompressor .\n\
<{MAP_ARN}> rdf:type aff4:Map ; \
aff4:size {virtual_size} ; \
aff4:dependentStream <{IMAGE_STREAM_ARN}> ; \
aff4:mapGapDefaultStream aff4:Zero .\n"
);
let mut map_bin = Vec::with_capacity(28);
map_bin.extend_from_slice(&512u64.to_le_bytes()); map_bin.extend_from_slice(&512u64.to_le_bytes()); map_bin.extend_from_slice(&0u64.to_le_bytes()); map_bin.extend_from_slice(&0u32.to_le_bytes());
let idx = format!("{IMAGE_STREAM_ARN}\n");
let cursor = std::io::Cursor::new(Vec::<u8>::new());
let mut zw = ZipWriter::new(cursor);
let opts = SimpleFileOptions::default().compression_method(CompressionMethod::Stored);
zw.start_file("information.turtle", opts).expect("start turtle");
zw.write_all(turtle.as_bytes()).expect("write turtle");
zw.start_file(&format!("{IMAGE_ZIP_BASE}/00000000"), opts).expect("start bevy");
zw.write_all(&chunk).expect("write bevy");
zw.start_file(&format!("{IMAGE_ZIP_BASE}/00000000.index"), opts).expect("start index");
zw.write_all(&(CHUNK_SIZE as u32).to_le_bytes()).expect("write index");
zw.start_file(&format!("{MAP_ZIP_BASE}/map"), opts).expect("start map");
zw.write_all(&map_bin).expect("write map");
zw.start_file(&format!("{MAP_ZIP_BASE}/idx"), opts).expect("start idx");
zw.write_all(idx.as_bytes()).expect("write idx");
zw.finish().expect("finish zip").into_inner()
}
pub fn test_aff4_scudette(data: &[u8]) -> Vec<u8> {
let mut chunk = vec![0u8; CHUNK_SIZE];
let n = data.len().min(CHUNK_SIZE);
chunk[..n].copy_from_slice(&data[..n]);
let turtle = format!(
"@prefix rdf: <http://www.w3.org/1999/02/22-rdf-syntax-ns#> .\n\
@prefix aff4: <http://aff4.org/Schema#> .\n\
<{STREAM_ARN}> rdf:type aff4:ImageStream ; \
aff4:size {CHUNK_SIZE} ; \
aff4:chunkSize {CHUNK_SIZE} ; \
aff4:chunksInSegment 1 ; \
aff4:compressionMethod aff4:NullCompressor .\n"
);
let cursor = std::io::Cursor::new(Vec::<u8>::new());
let mut zw = ZipWriter::new(cursor);
let opts = SimpleFileOptions::default().compression_method(CompressionMethod::Stored);
zw.start_file("information.turtle", opts).expect("start turtle");
zw.write_all(turtle.as_bytes()).expect("write turtle");
let bevy_name = format!("{ZIP_BASE}/00000000");
zw.start_file(bevy_name.as_str(), opts).expect("start bevy");
zw.write_all(&chunk).expect("write bevy");
let index_name = format!("{ZIP_BASE}/00000000.index");
zw.start_file(index_name.as_str(), opts).expect("start index");
zw.write_all(&0u32.to_le_bytes()).expect("write index start");
zw.write_all(&(CHUNK_SIZE as u32).to_le_bytes()).expect("write index end");
zw.finish().expect("finish zip").into_inner()
}