use std::io::{Write};
use fixedbitset::FixedBitSet;
use crate::Graph6Error;
pub fn write_size<W: Write>(buffer: &mut W, size: usize) -> Result<usize, Graph6Error> {
if size < 63 {
buffer.write(&[(size + 63) as u8])?;
Ok(1)
} else if size < 258048 {
buffer.write(&[126])?;
todo!()
} else if size < 68719476736 {
todo!()
} else {
Err(Graph6Error::GraphTooLarge)
}
}
pub fn get_size(bytes: &[u8]) -> Result<(usize, &[u8]), Graph6Error> {
match bytes {
[b'~', b'~', x1, x2, x3, x4, x5, x6, rest @ ..] => {
let x1 = (*x1 - b'?') as usize;
let x2 = (*x2 - b'?') as usize;
let x3 = (*x3 - b'?') as usize;
let x4 = (*x4 - b'?') as usize;
let x5 = (*x5 - b'?') as usize;
let x6 = (*x6 - b'?') as usize;
let size = x1 << 30 | x2 << 24 | x3 << 18 | x4 << 12 | x5 << 6 | x6;
Ok((size, rest))
}
[b'~', x1, x2, x3, rest @ ..] => {
let x1 = (*x1 - b'?') as usize;
let x2 = (*x2 - b'?') as usize;
let x3 = (*x3 - b'?') as usize;
let size = x1 << 12 | x2 << 6 | x3;
Ok((size, rest))
}
[x0, rest @ ..] => {
let size = *x0 - b'?';
Ok((size as usize, rest))
}
_ => Err(Graph6Error::InvalidSize),
}
}
pub fn base64_to_base256() {
todo!()
}
pub fn base256_to_base64(base256: &[u8]) -> Result<Vec<u8>, Graph6Error> {
let mut base64 = Vec::with_capacity(base256.len() * 4 / 3);
for byte in base256 {
let mut byte = *byte;
for _ in 0..4 {
base64.push((byte & 0b111111) as u8);
byte >>= 6;
}
}
Ok(base64)
}
pub fn fill_bitset(base64: &[u8], length: usize) -> Result<FixedBitSet, Graph6Error> {
let mut bitset = FixedBitSet::with_capacity(length);
let mut index = 0;
for byte in base64 {
let mask = *byte - b'?';
for i in (0u8..6).rev() {
if index < length {
bitset.set(index, mask & (1 << i) != 0);
}
index += 1;
}
}
Ok(bitset)
}