use std::fs::File;
use std::io::prelude::*;
use std::io::ErrorKind;
use guff::*;
pub struct HeaderV1 {
pub k : usize,
pub w : usize,
pub chunk_start : usize,
pub chunk_next : usize,
pub xform_data : Vec<u8>,
pub large_k : bool,
pub large_w : bool,
pub is_final : bool,
pub xform : bool,
}
pub fn read_sharefile_header(_file : &mut File)
-> Result<HeaderV1,String>
{
let k = 4;
let w = 1;
let chunk_start = 0;
let chunk_next = 0;
let large_k = false;
let large_w = false;
let is_final = true;
let xform = true;
let xform_data = vec![0u8; 14];
Ok(HeaderV1 {
k, w, chunk_start, chunk_next, large_k, large_w,
is_final, xform, xform_data
})
}
pub fn encode_length(mut n : usize) -> Vec<u8> {
let mut shifts = 0;
let mut v = Vec::<u8>::with_capacity(8);
while n > 0 {
v.push(n as u8);
n = n >> 8;
shifts += 1;
}
v.push(shifts);
v.reverse();
v
}
pub fn write_sharefile_header(file : &mut File, header : &HeaderV1)
-> Result<usize, std::io::Error>
{
let mut buffer = Vec::<u8>::with_capacity(30);
buffer.push('S' as u8);
buffer.push('F' as u8);
buffer.push(1);
let mut options = 0;
if header.large_k { options |= 1 }
if header.large_w { options |= 2 }
if header.is_final { options |= 4 }
if header.xform { options |= 8 }
buffer.push(options);
if header.large_k {
buffer.push(((header.k >> 8) & 255) as u8);
}
buffer.push((header.k & 255) as u8);
if header.large_w {
buffer.push(((header.w >> 8) & 255) as u8);
}
buffer.push((header.w & 255) as u8);
buffer.extend(encode_length(header.chunk_start).iter());
buffer.extend(encode_length(header.chunk_next).iter());
buffer.extend(header.xform_data.iter());
let length = buffer.len();
match file.write(&buffer) {
Ok(n) => {
if n != length {
Err(std::io::Error::new(
ErrorKind::Other,
format!("Failed to write all {} header bytes",
length)))
} else {
Ok(n)
}
},
Err(x) => { Err(x) },
}
}