Skip to content

Instantly share code, notes, and snippets.

@amlwwalker
Created January 11, 2020 16:36
Show Gist options
  • Save amlwwalker/dfcb77df565f2a1781c88f1c2bbc8d2d to your computer and use it in GitHub Desktop.
Save amlwwalker/dfcb77df565f2a1781c88f1c2bbc8d2d to your computer and use it in GitHub Desktop.
konsorten/go-xdeta encode/decode/apply
package main
import (
"context"
"fmt"
"os"
"github.com/dustin/go-humanize"
"github.com/konsorten/go-xdelta"
)
var original string
var to string
var patch string
var applied string
func main() {
original = "./moon.png"
to = "./moon-to.png"
patch = "./moon.patch"
applied = "./moon-applied.png"
if err := runEncode(); err != nil {
fmt.Printf("runEncode returned error ", err)
}
if err := dumpPatchInfo(); err != nil {
fmt.Printf("dumpPatchInfo returned error ", err)
}
if err := applyPatch(); err != nil {
fmt.Printf("applyPatch returned error ", err)
}
}
func runEncode() error {
// open the files
fromFile, err := os.Open(original)
if err != nil {
fmt.Printf("Failed to open FROM file: %v", err)
return err
}
defer fromFile.Close()
toFile, err := os.Open(to)
if err != nil {
fmt.Printf("Failed to open TO file: %v", err)
return err
}
defer toFile.Close()
patchFile, err := os.Create(patch)
if err != nil {
fmt.Printf("Failed to open PATCH file: %v", err)
return err
}
defer patchFile.Close()
options := xdelta.EncoderOptions{
FileID: "TestFullRoundtrip",
FromFile: fromFile,
ToFile: toFile,
PatchFile: patchFile,
}
enc, err := xdelta.NewEncoder(options)
if err != nil {
return err
}
defer enc.Close()
// ctx := context.Background()
// create the patch
err = enc.Process(context.TODO())
if err != nil {
return err
}
return nil
}
func dumpPatchInfo() error {
patchFileStat, err := os.Stat(patch)
if err != nil {
fmt.Printf("Failed to get patch filesize: %v", err)
return err
}
fmt.Printf("PATCH file size: %v (%v)", patchFileStat.Size(), humanize.Bytes(uint64(patchFileStat.Size())))
return nil
}
func applyPatch() error {
// open the files
fromFile, err := os.Open(original)
if err != nil {
fmt.Printf("Failed to open FROM file: %v", err)
return err
}
defer fromFile.Close()
appliedFile, err := os.Create(applied)
if err != nil {
fmt.Printf("Failed to open APPLIED file: %v", err)
return err
}
defer appliedFile.Close()
patchFile, err := os.Open(patch)
if err != nil {
fmt.Printf("Failed to open PATCH file: %v", err)
return err
}
defer patchFile.Close()
// prepare decoder
options := xdelta.DecoderOptions{
FileID: "TestFullRoundtrip",
FromFile: fromFile,
ToFile: appliedFile,
PatchFile: patchFile,
}
dec, err := xdelta.NewDecoder(options)
if err != nil {
fmt.Printf("Failed to create decoder: %v", err)
return err
}
defer dec.Close()
// retrieve header
// headerChannel := make(chan []byte, 1)
// dec.Header = headerChannel
// apply the patch
err = dec.Process(context.TODO())
if err != nil {
fmt.Printf("Failed to apply patch: %v", err)
return err
}
// compare the header
// readHeader := <-headerChannel
// if !bytes.Equal(ctx.Header, readHeader) {
// fmt.Printf("Header of PATCH file does not match")
// return err
// }
return nil
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment