use std::fs::File;
use std::io::{Read, Seek, SeekFrom};
use std::path::Path;
use crate::error::Error;
use crate::models::MAGIC_V01;
use crate::reader::Reader;
pub type LegacyReader<R> = Reader<R>;
pub fn is_legacy_format<R: Read + Seek>(reader: &mut R) -> Result<bool, Error> {
let pos = reader.stream_position()?;
let mut magic = [0u8; 8];
reader.read_exact(&mut magic)?;
reader.seek(SeekFrom::Start(pos))?;
Ok(magic == *MAGIC_V01)
}
pub fn is_legacy_file(path: impl AsRef<Path>) -> Result<bool, Error> {
let mut file = File::open(path)?;
is_legacy_format(&mut file)
}
#[cfg(test)]
mod tests {
use super::*;
use std::io::Cursor;
#[test]
fn test_is_legacy_format() {
let v01_data = b"ZTEN0001";
let v11_data = b"ZTEN1000";
let mut cursor = Cursor::new(v01_data.to_vec());
assert!(is_legacy_format(&mut cursor).unwrap());
let mut cursor = Cursor::new(v11_data.to_vec());
assert!(!is_legacy_format(&mut cursor).unwrap());
}
#[test]
fn test_legacy_mmap() -> Result<(), Box<dyn std::error::Error>> {
use std::io::Write;
use tempfile::NamedTempFile;
let mut file = NamedTempFile::new()?;
let path = file.path().to_path_buf();
file.write_all(MAGIC_V01)?;
let padding = vec![0u8; 56];
file.write_all(&padding)?;
let data: Vec<f32> = vec![1.0, 2.0, 3.0, 4.0];
let bytes: &[u8] = bytemuck::cast_slice(&data);
let offset = 64u64;
let size = bytes.len() as u64;
file.write_all(bytes)?;
#[derive(serde::Serialize)]
struct LegacyTensorMetaSer {
name: String,
offset: u64,
size: u64,
dtype: String,
shape: Vec<u64>,
encoding: String,
layout: String,
}
let meta = LegacyTensorMetaSer {
name: "tensor1".to_string(),
offset,
size,
dtype: "float32".to_string(),
shape: vec![4],
encoding: "raw".to_string(),
layout: "dense".to_owned(),
};
let manifest = vec![meta];
let mut cbor_data = Vec::new();
ciborium::into_writer(&manifest, &mut cbor_data)?;
file.write_all(&cbor_data)?;
file.write_all(&(cbor_data.len() as u64).to_le_bytes())?;
file.flush()?;
let reader = Reader::open_mmap_any(&path)?;
let slice = reader.view("tensor1")?;
assert_eq!(slice, bytes);
let typed_slice = reader.view_as::<f32>("tensor1")?;
assert_eq!(typed_slice, &data);
Ok(())
}
}