tsfile/encoding/
decoder.rs

1use crate::utils::cursor;
2use crate::utils::cursor::PackWidthReader;
3use byteorder::{BigEndian, ReadBytesExt};
4use snafu::{ResultExt, Snafu};
5use std::io::Cursor;
6
7#[derive(Debug, Snafu)]
8pub enum Error {
9    #[snafu(display("Unable to read cursor data: {}", source))]
10    ReadCursorData { source: std::io::Error },
11    #[snafu(display("Unable to read packed data: {}", source))]
12    ReadPackedData { source: cursor::Error },
13}
14
15type Result<T, E = Error> = std::result::Result<T, E>;
16
17#[derive(Debug)]
18pub enum Field {
19    Boolean(bool),
20    Int32(i32),
21    Int64(i64),
22    FLOAT(f32),
23    DOUBLE(f64),
24    TEXT(Vec<u8>),
25}
26
27pub trait Decoder {
28    fn new() -> Self
29    where
30        Self: Sized;
31    fn decode(&self, data: &mut Cursor<Vec<u8>>) -> Result<Vec<Field>>;
32}
33
34pub trait BinaryDelta: Decoder {}
35
36pub struct LongBinaryDecoder {}
37
38impl Decoder for LongBinaryDecoder {
39    fn new() -> Self {
40        Self {}
41    }
42
43    fn decode(&self, data: &mut Cursor<Vec<u8>>) -> Result<Vec<Field>> {
44        let pack_num = data.read_i32::<BigEndian>().context(ReadCursorData)?;
45        let pack_width = data.read_i32::<BigEndian>().context(ReadCursorData)?;
46        let min_delta_base = data.read_i64::<BigEndian>().context(ReadCursorData)?;
47        let mut previous = data.read_i64::<BigEndian>().context(ReadCursorData)?;
48        let mut result = Vec::with_capacity(pack_num as usize);
49
50        for i in 0..pack_num {
51            let value = data
52                .read_pack_width_long(pack_width * i, pack_width)
53                .context(ReadPackedData)?;
54            previous = previous + min_delta_base + value;
55            result.push(Field::Int64(previous));
56        }
57
58        Ok(result)
59    }
60}
61
62pub trait PlainDecoder: Decoder {}
63
64pub struct IntPlainDecoder {}
65
66impl Decoder for IntPlainDecoder {
67    fn new() -> Self {
68        Self {}
69    }
70
71    fn decode(&self, data: &mut Cursor<Vec<u8>>) -> Result<Vec<Field>> {
72        let mut result = Vec::new();
73        while data.position() < data.get_ref().len() as u64 {
74            result.push(Field::Int32(
75                data.read_i32::<BigEndian>().context(ReadCursorData)?,
76            ));
77        }
78
79        Ok(result)
80    }
81}