use self::serde::Type;
use std::io::{self, ErrorKind};
mod error;
pub(crate) mod serde;
pub(crate) mod size;
mod untyped;
pub use self::error::Error;
pub use self::serde::{TtF32, TtF64};
pub use untyped::{Key, Value};
#[derive(Debug, Clone)]
pub(crate) struct Node<'d> {
children_length: usize,
value_data: &'d [u8],
value_type: Type,
key_data: &'d [u8],
key_type: Type,
}
impl<'v, 'd: 'v> Node<'v> {
#[inline(always)]
pub fn from_bytes(&mut self, data: &'d [u8]) -> Result<usize, Error> {
let (vlen, size) = decode_var(&data)?;
let mut read = size;
let (klen, size) = decode_var(&data[read..])?;
read += size;
if data.len() - read < (1 + vlen + 1 + klen + 1) as usize {
return Err(Error::OutOfSpace());
}
self.value_type = Type::from_u8(data[read]);
read += 1;
self.value_data = &data[read..read + vlen as usize];
read += vlen as usize;
self.key_type = Type::from_u8(data[read]);
read += 1;
self.key_data = &data[read..read + klen as usize];
read += klen as usize;
let (clen, size) = decode_var(&data[read..])?;
self.children_length = clen;
Ok(read + size)
}
}
impl Default for Node<'_> {
fn default() -> Node<'static> {
Node {
children_length: 0,
value_data: &[],
value_type: Default::default(),
key_data: &[],
key_type: Default::default(),
}
}
}
pub(crate) fn write_key_value<K: serde::KeyEncodable, V: serde::ValueEncodable, W>(
key: &K,
value: &V,
out: &mut W,
) -> Result<(), Error>
where
W: io::Write,
{
let mut buf = [0 as u8; 10];
let mut buflen: usize;
buflen = encode_var(value.len(), &mut buf);
out.write_all(&buf[0..buflen])?;
buflen = encode_var(key.len(), &mut buf);
out.write_all(&buf[0..buflen])?;
out.write_all(&value.ttype().to_le_bytes())?;
value.write_bytes(out)?;
out.write_all(&key.ttype().to_le_bytes())?;
key.write_bytes(out)?;
buflen = encode_var(value.len_children(), &mut buf);
out.write_all(&buf[0..buflen])?;
value.write_children(out)?;
Ok(())
}
pub(crate) fn write_key_value_buf<K: serde::KeyEncodable, V: serde::ValueEncodable, W>(
key: &K,
value: &V,
out: &mut W,
buf: &mut [u8; 10],
) -> Result<(), Error>
where
W: io::Write,
{
let mut buflen: usize;
buflen = encode_var(value.len(), buf);
out.write_all(&buf[0..buflen])?;
buflen = encode_var(key.len(), buf);
out.write_all(&buf[0..buflen])?;
out.write_all(&value.ttype().to_le_bytes())?;
value.write_bytes(out)?;
out.write_all(&key.ttype().to_le_bytes())?;
key.write_bytes(out)?;
buflen = encode_var(value.len_children(), buf);
out.write_all(&buf[0..buflen])?;
value.write_children(out)?;
Ok(())
}
#[derive(Debug, Clone)]
pub(crate) struct ReadNode {
value_length: usize,
key_length: usize,
}
impl ReadNode {
#[inline(always)]
pub fn read_lengths<R: io::Read>(&mut self, r: &mut R) -> Result<(), Error> {
self.value_length = decode_var_reader(r)?;
self.key_length = decode_var_reader(r)?;
Ok(())
}
}
impl Default for ReadNode {
fn default() -> ReadNode {
ReadNode {
value_length: 0,
key_length: 0,
}
}
}
#[inline(always)]
pub(crate) fn read_byte<R: io::Read>(r: &mut R) -> Option<u8> {
let mut buf = [0];
loop {
match r.read(&mut buf) {
Ok(0) => return None,
Ok(_) => return Some(buf[0]),
Err(ref e) if e.kind() == ErrorKind::Interrupted => {}
Err(_e) => return None,
};
}
}
#[inline(always)]
pub(crate) fn discard_var_reader<R: io::Read>(r: &mut R) {
loop {
match read_byte(r) {
Some(b) if b & 0x80 == 0 => return,
None => return,
Some(_) => {}
};
}
}
#[inline(always)]
pub(crate) fn decode_var_reader<R: io::Read>(r: &mut R) -> Result<usize, Error> {
let mut x = 0;
let mut s = 0;
loop {
let b = match read_byte(r) {
Some(b) => b,
None => return Err(Error::OutOfSpace()),
};
x |= (b << s) as usize;
s += 7;
if b & 0x80 == 0 {
if s > 10 * 7 || s == 10 * 7 && b > 1 {
return Err(Error::new(
"The decoded varint is to big, the input data is likely corrupt",
));
}
return Ok(x);
}
}
}
#[inline(always)]
pub(crate) fn decode_var(src: &[u8]) -> Result<(usize, usize), Error> {
let mut x = 0;
let mut s = 0;
let mut i = 0;
let mut iter = src.iter();
loop {
let b = match iter.next() {
Some(b) => b,
None => return Err(Error::OutOfSpace()),
};
i += 1;
x |= (b << s) as usize;
s += 7;
if b & 0x80 == 0 {
if s > 10 * 7 || s == 10 * 7 && b > &1 {
return Err(Error::new(
"The decoded varint is to big, the input data is likely corrupt",
));
}
return Ok((x, i));
}
s += 7;
}
}
#[inline(always)]
pub(crate) fn encode_var(mut u: usize, dst: &mut [u8; 10]) -> usize {
let mut i = 0;
while u >= 0x80 {
dst[i] = u as u8 | 0x80;
u >>= 7;
i += 1;
}
dst[i] = u as u8;
i + 1
}
#[inline(always)]
fn size_var(mut v: usize) -> usize {
let mut i = 0;
while v >= 0x80 {
v >>= 7;
i += 1;
}
i + 1
}