fork of go-gitdiff with jj support
at v0.8.1 2.0 kB view raw
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}