From 8ae6cb2e9617a93d8de5f1409e8c268ec4921144 Mon Sep 17 00:00:00 2001 From: Andrew Gutekanst Date: Wed, 4 Mar 2020 10:52:34 -0500 Subject: [PATCH] Use bytes.Reader for deltacomp --- .../compression/deltacomp/deltacomp.go | 94 ++++++++++++++++++- 1 file changed, 91 insertions(+), 3 deletions(-) diff --git a/server/channelserver/compression/deltacomp/deltacomp.go b/server/channelserver/compression/deltacomp/deltacomp.go index 4c4cc07a7..66414a357 100644 --- a/server/channelserver/compression/deltacomp/deltacomp.go +++ b/server/channelserver/compression/deltacomp/deltacomp.go @@ -1,11 +1,98 @@ package deltacomp import ( - "errors" - - "github.com/Andoryuuta/byteframe" + "io" + "bytes" ) + +func checkReadUint8(r *bytes.Reader) (uint8, error) { + b, err := r.ReadByte() + if err != nil { + return 0, err + } + return b, nil +} + +func checkReadUint16(r *bytes.Reader) (uint16, error) { + data := make([]byte, 2) + n, err := r.Read(data) + if err != nil { + return 0, err + } else if n != len(data) { + return 0, io.EOF + } + + return uint16(data[0])<<8 | uint16(data[1]), nil +} + +func readCount(r *bytes.Reader) (int, error) { + var count int + + count8, err := checkReadUint8(r) + if err != nil { + return 0, err + } + count = int(count8) + + if count == 0 { + count16, err := checkReadUint16(r) + if err != nil { + return 0, err + } + count = int(count16) + } + + return int(count), nil +} + +// ApplyDataDiff applies a delta data diff patch onto given base data. +func ApplyDataDiff(diff []byte, baseData []byte) []byte { + // Make a copy of the base data to return, + // (probably just make this modify the given slice in the future). + baseCopy := make([]byte, len(baseData)) + copy(baseCopy, baseData) + + patch := bytes.NewReader(diff) + + // The very first matchCount is +1 more than it should be, so we start at -1. + dataOffset := -1 + for { + // Read the amount of matching bytes. + matchCount, err := readCount(patch) + if err != nil { + // No more data + break + } + + dataOffset += matchCount + + // Read the amount of differing bytes. + differentCount, err := readCount(patch) + if err != nil { + // No more data + break + } + differentCount -= 1 + + // Apply the patch bytes. + for i := 0; i < differentCount; i++ { + b, err := checkReadUint8(patch) + if err != nil { + panic("Invalid or misunderstood patch format!") + } + baseCopy[dataOffset+i] = b + } + + dataOffset += differentCount - 1 + + } + + return baseCopy +} + + +/* func checkReadUint8(bf *byteframe.ByteFrame) (uint8, error) { if len(bf.DataFromCurrent()) >= 1 { return bf.ReadUint8(), nil @@ -84,3 +171,4 @@ func ApplyDataDiff(diff []byte, baseData []byte) []byte { return baseCopy } +*/ \ No newline at end of file