Contact card decompress, split, merge

This commit is contained in:
ycc 2022-11-29 22:19:54 +01:00
parent b464a855ae
commit d5760e8439
3 changed files with 129 additions and 3 deletions

66
buffer.go Normal file
View File

@ -0,0 +1,66 @@
package meowlib
import (
"errors"
"strconv"
)
func min(a, b int) int {
if a <= b {
return a
}
return b
}
func BufferSplit(buffer []byte, parts uint8) (packets [][]byte, err error) {
if int(parts) > len(buffer) {
return nil, errors.New("too many parts(" + strconv.Itoa(int(parts)) + ") for buffer len(" + strconv.Itoa(len(buffer)) + ")")
}
chunksize := int(len(buffer)/int(parts)) + 1
packets = make([][]byte, parts)
for c := 0; c < int(parts); c++ {
if c == 0 {
packets[c] = []byte{byte(c), byte(parts)}
} else {
packets[c] = []byte{byte(c)}
}
}
chunk := 0
for i := 0; i < len(buffer); i += chunksize {
batch := buffer[i:min(i+chunksize, len(buffer))]
packets[chunk] = append(packets[chunk], batch...)
chunk++
}
return packets, nil
}
func BufferMerge(packets [][]byte) (buffer []byte, err error) {
var parts int
found := false
buffer = []byte{}
for _, b := range packets {
if b[0] == 0 {
parts = int(b[1])
buffer = append(buffer, b[2:]...)
found = true
break
}
}
if !found {
return nil, errors.New("start packet not found")
}
for i := 1; i < parts; i++ {
found = false
for _, b := range packets {
if b[0] == byte(i) {
buffer = append(buffer, b[1:]...)
found = true
break
}
}
if !found {
return nil, errors.New("packet #" + strconv.Itoa(i) + " not found")
}
}
return buffer, nil
}

24
buffer_test.go Normal file
View File

@ -0,0 +1,24 @@
package meowlib
import (
"log"
"testing"
"github.com/stretchr/testify/assert"
)
func TestBufferSplit(t *testing.T) {
source := []byte("Hello World, I need to slice you, but in equal parts, not the capitalist way")
packets, err := BufferSplit(source, 3)
if err != nil {
log.Fatalln("Failed to encode address book:", err)
}
println(len(packets))
destination, err := BufferMerge(packets)
if err != nil {
log.Fatalln("Failed to encode address book:", err)
}
println(string(destination))
assert.Equal(t, source, destination, "The two buffers should be the same.")
}

View File

@ -43,17 +43,53 @@ func (contact *ContactCard) Compress() ([]byte, error) {
return nil, err
}
var b bytes.Buffer
gz := gzip.NewWriter(&b)
gz, err := gzip.NewWriterLevel(&b, gzip.BestCompression)
if err != nil {
return nil, err
}
if _, err := gz.Write(out); err != nil {
log.Fatal(err)
return nil, err
}
if err := gz.Close(); err != nil {
log.Fatal(err)
return nil, err
}
fmt.Println(b.Bytes())
return b.Bytes(), nil
}
func (contact *ContactCard) Split(parts uint8) (packets [][]byte, err error) {
data, err := contact.Compress()
if err != nil {
return nil, err
}
return BufferSplit(data, parts)
}
func NewContactCardFromCompressed(compressed []byte) (*ContactCard, error) {
cc := &ContactCard{}
reader := bytes.NewReader([]byte(compressed))
gzreader, err := gzip.NewReader(reader)
if err != nil {
return nil, err
}
output, err := ioutil.ReadAll(gzreader)
if err != nil {
return nil, err
}
if err := proto.Unmarshal(output, cc); err != nil {
return nil, err
}
return cc, nil
}
func NewContactCardFromSplit(packets [][]byte) (*ContactCard, error) {
data, err := BufferMerge(packets)
if err != nil {
return nil, err
}
return NewContactCardFromCompressed(data)
}
func (contact *ContactCard) WriteCompressed(filename string) error {
out, err := contact.Compress()
if err != nil {