// Package headers provides headers for the db binary files package headers import ( "encoding/binary" "errors" ) type Headers struct { HeaderString []byte // Header string PageSize uint64 // Page size for chunks DBVersion uint16 // Version of the db // Reserved for future use. WAL bool // Enable write-ahead-logging Commit []byte // SHA256 sum of the current DB - Could be switched to ULID/UUID in future. } // constant HeaderString const HeaderString = "zutto/db/" //Commit data length - mapped to be 32 bytes for now, to match SHA256SUM const CommitDataLength = 32 // Static lengths of the headers HeaderString length(uint16, 2 bytes)- Pagesize (uint64, 8 bytes) + DBVersion (int16, 2 bytes) + WAL (int8//bool, 1 byte) + Commit (SHA256 32 bytes) const StaticHeadersLength = 13 + CommitDataLength // Generate generates []byte output from the headers func (h *Headers) Generate() *[]byte { var HeaderStringLength int = len(h.HeaderString) //Output array var data []byte = make([]byte, HeaderStringLength+StaticHeadersLength) //Headerstring binary.LittleEndian.PutUint16(data[0:2], uint16(HeaderStringLength)) copy(data[2:2+HeaderStringLength], h.HeaderString[:]) //add the simpler metadata binary.LittleEndian.PutUint64(data[2+HeaderStringLength:10+HeaderStringLength], h.PageSize) binary.LittleEndian.PutUint16(data[10+HeaderStringLength:12+HeaderStringLength], h.DBVersion) //Convert bool-value to byte with a helper function true = byte(1), false = byte(0) data[12+HeaderStringLength] = ToSingleByte(h.WAL) //commit data, extr copy(data[13+HeaderStringLength:13+CommitDataLength+HeaderStringLength], h.Commit[0:CommitDataLength]) return &data } // Parse parses the headers // Accepts 2 parameters, Input *[]byte's and Padding // Returns error in case of errors. func (h *Headers) Parse(Input *[]byte, Padding int) error { if Padding+len((*Input)) < StaticHeadersLength { return errors.New("Input was not correct length") } var HeaderStringLength int = int(binary.LittleEndian.Uint16((*Input)[Padding : Padding+2])) h.HeaderString = (*Input)[2+Padding : Padding+2+HeaderStringLength] h.PageSize = binary.LittleEndian.Uint64((*Input)[2+HeaderStringLength+Padding : Padding+10+HeaderStringLength]) h.DBVersion = binary.LittleEndian.Uint16((*Input)[10+HeaderStringLength+Padding : Padding+12+HeaderStringLength]) h.WAL = ByteToBool((*Input)[12+HeaderStringLength]) h.Commit = ((*Input)[13+HeaderStringLength+Padding : Padding+13+CommitDataLength+HeaderStringLength]) return nil }