fork of go-gitdiff with jj support
1package gitdiff
2
3import (
4 "fmt"
5)
6
7var (
8 b85Table map[byte]byte
9 b85Alpha = []byte(
10 "0123456789" + "ABCDEFGHIJKLMNOPQRSTUVWXYZ" + "abcdefghijklmnopqrstuvwxyz" + "!#$%&()*+-;<=>?@^_`{|}~",
11 )
12)
13
14func init() {
15 b85Table = make(map[byte]byte)
16 for i, c := range b85Alpha {
17 b85Table[c] = byte(i)
18 }
19}
20
21// base85Decode decodes Base85-encoded data from src into dst. It uses the
22// alphabet defined by base85.c in the Git source tree. src must contain at
23// least len(dst) bytes of encoded data.
24func base85Decode(dst, src []byte) error {
25 var v uint32
26 var n, ndst int
27 for i, b := range src {
28 if b, ok := b85Table[b]; ok {
29 v = 85*v + uint32(b)
30 n++
31 } else {
32 return fmt.Errorf("invalid base85 byte at index %d: 0x%X", i, src[i])
33 }
34 if n == 5 {
35 rem := len(dst) - ndst
36 for j := 0; j < 4 && j < rem; j++ {
37 dst[ndst] = byte(v >> 24)
38 ndst++
39 v <<= 8
40 }
41 v = 0
42 n = 0
43 }
44 }
45 if n > 0 {
46 return fmt.Errorf("base85 data terminated by underpadded sequence")
47 }
48 if ndst < len(dst) {
49 return fmt.Errorf("base85 data underrun: %d < %d", ndst, len(dst))
50 }
51 return nil
52}
53
54// base85Encode encodes src in Base85, writing the result to dst. It uses the
55// alphabet defined by base85.c in the Git source tree.
56func base85Encode(dst, src []byte) {
57 var di, si int
58
59 encode := func(v uint32) {
60 dst[di+0] = b85Alpha[(v/(85*85*85*85))%85]
61 dst[di+1] = b85Alpha[(v/(85*85*85))%85]
62 dst[di+2] = b85Alpha[(v/(85*85))%85]
63 dst[di+3] = b85Alpha[(v/85)%85]
64 dst[di+4] = b85Alpha[v%85]
65 }
66
67 n := (len(src) / 4) * 4
68 for si < n {
69 encode(uint32(src[si+0])<<24 | uint32(src[si+1])<<16 | uint32(src[si+2])<<8 | uint32(src[si+3]))
70 si += 4
71 di += 5
72 }
73
74 var v uint32
75 switch len(src) - si {
76 case 3:
77 v |= uint32(src[si+2]) << 8
78 fallthrough
79 case 2:
80 v |= uint32(src[si+1]) << 16
81 fallthrough
82 case 1:
83 v |= uint32(src[si+0]) << 24
84 encode(v)
85 }
86}
87
88// base85Len returns the length of n bytes of Base85 encoded data.
89func base85Len(n int) int {
90 return (n + 3) / 4 * 5
91}