1
  2
  3
  4
  5
  6
  7
  8
  9
 10
 11
 12
 13
 14
 15
 16
 17
 18
 19
 20
 21
 22
 23
 24
 25
 26
 27
 28
 29
 30
 31
 32
 33
 34
 35
 36
 37
 38
 39
 40
 41
 42
 43
 44
 45
 46
 47
 48
 49
 50
 51
 52
 53
 54
 55
 56
 57
 58
 59
 60
 61
 62
 63
 64
 65
 66
 67
 68
 69
 70
 71
 72
 73
 74
 75
 76
 77
 78
 79
 80
 81
 82
 83
 84
 85
 86
 87
 88
 89
 90
 91
 92
 93
 94
 95
 96
 97
 98
 99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
use std::collections::HashMap;
use std::io::SeekFrom;

use crate::byte_size::globals::*;
use crate::database::table::types::*;
use crate::types::bv::{BvObject, BvString};
use crate::utils::serialize;

pub struct Writer<T: std::io::Write + std::io::Seek> {
    pub writer: T,
    pub curr_pos: usize,
    pub table_length: u32,
    pub kv_records_length: u64,
    pub table_rows_length: u64,
    pub decl_lu_map: HashMap<Vec<u8>, u64>,
}

impl<T: std::io::Write + std::io::Seek> Writer<T> {
    pub fn new(writer: T) -> Self {
        Writer {
            writer,
            curr_pos: 0,
            table_length: 0,
            kv_records_length: 0,
            table_rows_length: 0,
            decl_lu_map: HashMap::new(),
        }
    }

    pub fn write_header(&mut self) -> std::io::Result<usize> {
        let mut length = 0;
        self.writer.seek(SeekFrom::Start(8))?;
        length += self.writer.write(&serialize(&self.table_length))?;
        //length += self.writer.write(&serialize(&self.kv_records_length))?;
        length += self.writer.write(&serialize(&self.table_rows_length))?;

        Ok(length)
    }

    pub fn write_table(&mut self, name: &[u8], fields: &FieldMap) -> std::io::Result<u32> {
        // Identifier, name length, fields length, name, fields
        let ser_fields = serialize(fields);
        let mut length = 0;
        let mut curr_pos = self.curr_pos;

        length += self.writer.write(&table::IDENT)? as u32;

        length += self.writer.write(&[name.len() as u8])? as u32;
        length += self.writer.write(&serialize(&(ser_fields.len() as u16)))? as u32;

        length += self.writer.write(&name)? as u32;
        length += self.writer.write(&ser_fields)? as u32;

        let mut decl_lu_name = Vec::with_capacity(name.len() + "header_rdata_start".len());
        decl_lu_name.extend(name);
        decl_lu_name.extend(b"header_rdata_start");

        curr_pos += length as usize;
        self.decl_lu_map.insert(decl_lu_name, curr_pos as u64);
        length += self.writer.write(&serialize(&(0 as u64)))? as u32; // Records start
        length += self.writer.write(&serialize(&(0 as u64)))? as u32; // Total records length
        length += self.writer.write(&serialize(&(0 as u64)))? as u32; // Records count

        Ok(length)
    }

    pub fn write_table_rows_data(
        &mut self,
        name: &[u8],
        total_len: u64,
        records_count: u64,
    ) -> std::io::Result<()> {
        let mut decl_header_rdata_start =
            Vec::with_capacity(name.len() + "header_rdata_start".len());
        decl_header_rdata_start.extend(name);
        decl_header_rdata_start.extend(b"header_rdata_start");

        let mut decl_records_start = Vec::with_capacity(name.len() + "decl_records_start".len());
        decl_records_start.extend(name);
        decl_records_start.extend(b"decl_records_start");

        self.writer
            .seek(SeekFrom::Start(self.decl_lu_map[&decl_header_rdata_start]))?;
        self.writer
            .write_all(&serialize(&self.decl_lu_map[&decl_records_start]))?;
        self.writer.write_all(&serialize(&total_len))?;
        self.writer.write_all(&serialize(&records_count))?;

        Ok(())
    }

    pub fn write_kv_record(&mut self, record: (&BvString, &BvObject)) -> std::io::Result<u64> {
        // Identifier, name length, fields length, name, fields
        let (k, v) = record;
        assert!(k.len() as u8 > 0 && v.type_name().len() as u8 > 0);
        let mut length = 0;

        length += self.writer.write(&kv::IDENT)? as u64;

        // K, TN, V lengths
        length += self.writer.write(&[k.len() as u8])? as u64;
        length += self.writer.write(&[v.type_name().len() as u8])? as u64;
        length += self.writer.write(&serialize(&(v.raw().len() as u32)))? as u64;

        // Values
        length += self.writer.write(k.as_slice())? as u64;
        length += self.writer.write(v.type_name().as_slice())? as u64;
        length += self.writer.write(v.as_slice())? as u64;

        Ok(length)
    }

    pub fn write_decl_header(&mut self) -> std::io::Result<u64> {
        let mut length = 0;
        length += self.writer.write(&table::rows::IDENT)? as u64;
        Ok(length)
    }

    pub fn write_decl_record(&mut self, hm: &TableRow) -> std::io::Result<u64> {
        let ser_hm = serialize(hm);
        let mut length = 0;

        length += self.writer.write(&table::rows::RECORD_IDENT)? as u64;
        length += self.writer.write(&serialize(&(ser_hm.len() as u32)))? as u64;
        length += self.writer.write(&ser_hm)? as u64;

        Ok(length)
    }
}

impl<T: std::io::Write + std::io::Seek> std::ops::Deref for Writer<T> {
    type Target = T;

    fn deref(&self) -> &Self::Target {
        &self.writer
    }
}

impl<T: std::io::Write + std::io::Seek> std::ops::DerefMut for Writer<T> {
    fn deref_mut(&mut self) -> &mut Self::Target {
        &mut self.writer
    }
}