summaryrefslogtreecommitdiff
path: root/pkg/gitdiff/testdata/apply/bin.go
diff options
context:
space:
mode:
Diffstat (limited to 'pkg/gitdiff/testdata/apply/bin.go')
-rw-r--r--pkg/gitdiff/testdata/apply/bin.go124
1 files changed, 124 insertions, 0 deletions
diff --git a/pkg/gitdiff/testdata/apply/bin.go b/pkg/gitdiff/testdata/apply/bin.go
new file mode 100644
index 0000000..e34f06b
--- /dev/null
+++ b/pkg/gitdiff/testdata/apply/bin.go
@@ -0,0 +1,124 @@
+//go:build ignore
+
+// bin.go is a helper CLI to manipulate binary diff data for testing purposes.
+// It can decode patches generated by git using the standard parsing functions
+// or it can encode binary data back into the format expected by Git. It
+// operates on stdin writes results (possibly binary) to stdout.
+
+package main
+
+import (
+ "bytes"
+ "compress/zlib"
+ "encoding/binary"
+ "flag"
+ "io/ioutil"
+ "log"
+ "os"
+ "strings"
+
+ "github.com/bluekeyes/go-gitdiff/gitdiff"
+)
+
+var (
+ b85Powers = []uint32{52200625, 614125, 7225, 85, 1}
+ b85Alpha = []byte(
+ "0123456789" + "ABCDEFGHIJKLMNOPQRSTUVWXYZ" + "abcdefghijklmnopqrstuvwxyz" + "!#$%&()*+-;<=>?@^_`{|}~",
+ )
+)
+
+var mode string
+
+func base85Encode(data []byte) []byte {
+ chunks, remaining := len(data)/4, len(data)%4
+ if remaining > 0 {
+ data = append(data, make([]byte, 4-remaining)...)
+ chunks++
+ }
+
+ var n int
+ out := make([]byte, 5*chunks)
+
+ for i := 0; i < len(data); i += 4 {
+ v := binary.BigEndian.Uint32(data[i : i+4])
+ for j := 0; j < 5; j++ {
+ p := v / b85Powers[j]
+ out[n+j] = b85Alpha[p]
+ v -= b85Powers[j] * p
+ }
+ n += 5
+ }
+
+ return out
+}
+
+func compress(data []byte) ([]byte, error) {
+ var b bytes.Buffer
+ w := zlib.NewWriter(&b)
+
+ if _, err := w.Write(data); err != nil {
+ return nil, err
+ }
+ if err := w.Close(); err != nil {
+ return nil, err
+ }
+
+ return b.Bytes(), nil
+}
+
+func wrap(data []byte) string {
+ var s strings.Builder
+ for i := 0; i < len(data); i += 52 {
+ c := 52
+ if c > len(data)-i {
+ c = len(data) - i
+ }
+ b := (c / 5) * 4
+
+ if b <= 26 {
+ s.WriteByte(byte('A' + b - 1))
+ } else {
+ s.WriteByte(byte('a' + b - 27))
+ }
+ s.Write(data[i : i+c])
+ s.WriteByte('\n')
+ }
+ return s.String()
+}
+
+func init() {
+ flag.StringVar(&mode, "mode", "parse", "operation mode, one of 'parse' or 'encode'")
+}
+
+func main() {
+ flag.Parse()
+
+ switch mode {
+ case "parse":
+ files, _, err := gitdiff.Parse(os.Stdin)
+ if err != nil {
+ log.Fatalf("failed to parse file: %v", err)
+ }
+ if len(files) != 1 {
+ log.Fatalf("patch contains more than one file: %d", len(files))
+ }
+ if files[0].BinaryFragment == nil {
+ log.Fatalf("patch file does not contain a binary fragment")
+ }
+ os.Stdout.Write(files[0].BinaryFragment.Data)
+
+ case "encode":
+ data, err := ioutil.ReadAll(os.Stdin)
+ if err != nil {
+ log.Fatalf("failed to read input: %v", err)
+ }
+ data, err = compress(data)
+ if err != nil {
+ log.Fatalf("failed to compress data: %v", err)
+ }
+ os.Stdout.WriteString(wrap(base85Encode(data)))
+
+ default:
+ log.Fatalf("unknown mode: %s", mode)
+ }
+}