64 lines
1.3 KiB
Go
64 lines
1.3 KiB
Go
package db0305
|
|
|
|
import (
|
|
"encoding/binary"
|
|
"errors"
|
|
"hash/crc32"
|
|
"io"
|
|
)
|
|
|
|
type Entry struct {
|
|
key []byte
|
|
val []byte
|
|
deleted bool
|
|
}
|
|
|
|
func (ent *Entry) Encode() []byte {
|
|
data := make([]byte, 4+4+4+1+len(ent.key)+len(ent.val))
|
|
binary.LittleEndian.PutUint32(data[4:8], uint32(len(ent.key)))
|
|
copy(data[4+4+4+1:], ent.key)
|
|
if ent.deleted {
|
|
data[4+4+4] = 1
|
|
} else {
|
|
binary.LittleEndian.PutUint32(data[8:12], uint32(len(ent.val)))
|
|
copy(data[4+4+4+1+len(ent.key):], ent.val)
|
|
}
|
|
binary.LittleEndian.PutUint32(data[0:4], crc32.ChecksumIEEE(data[4:]))
|
|
return data
|
|
}
|
|
|
|
var ErrBadSum = errors.New("bad checksum")
|
|
|
|
func (ent *Entry) Decode(r io.Reader) error {
|
|
var header [4 + 4 + 4 + 1]byte
|
|
if _, err := io.ReadFull(r, header[:]); err != nil {
|
|
return err
|
|
}
|
|
klen := int(binary.LittleEndian.Uint32(header[4:8]))
|
|
vlen := int(binary.LittleEndian.Uint32(header[8:12]))
|
|
deleted := header[4+4+4]
|
|
|
|
data := make([]byte, klen+vlen)
|
|
if _, err := io.ReadFull(r, data); err != nil {
|
|
return err
|
|
}
|
|
|
|
h := crc32.NewIEEE()
|
|
h.Write(header[4:])
|
|
h.Write(data)
|
|
if h.Sum32() != binary.LittleEndian.Uint32(header[0:4]) {
|
|
return ErrBadSum
|
|
}
|
|
|
|
ent.key = data[:klen]
|
|
if deleted != 0 {
|
|
ent.deleted = true
|
|
} else {
|
|
ent.deleted = false
|
|
ent.val = data[klen:]
|
|
}
|
|
return nil
|
|
}
|
|
|
|
// QzBQWVJJOUhU https://trialofcode.org/
|