MCPcopy Create free account
hub / github.com/antonmedv/gitmal / ParseBinaryChunk

Method ParseBinaryChunk

pkg/gitdiff/binary.go:103–165  ·  view source on GitHub ↗
(frag *BinaryFragment)

Source from the content-addressed store, hash-verified

101}
102
103func (p *parser) ParseBinaryChunk(frag *BinaryFragment) error {
104 // Binary fragments are encoded as a series of base85 encoded lines. Each
105 // line starts with a character in [A-Za-z] giving the number of bytes on
106 // the line, where A = 1 and z = 52, and ends with a newline character.
107 //
108 // The base85 encoding means each line is a multiple of 5 characters + 2
109 // additional characters for the length byte and the newline. The fragment
110 // ends with a blank line.
111 const (
112 shortestValidLine = "A00000\n"
113 maxBytesPerLine = 52
114 )
115
116 var data bytes.Buffer
117 buf := make([]byte, maxBytesPerLine)
118 for {
119 line := p.Line(0)
120 if line == "\n" {
121 break
122 }
123 if len(line) < len(shortestValidLine) || (len(line)-2)%5 != 0 {
124 return p.Errorf(0, "binary patch: corrupt data line")
125 }
126
127 byteCount, seq := int(line[0]), line[1:len(line)-1]
128 switch {
129 case 'A' <= byteCount && byteCount <= 'Z':
130 byteCount = byteCount - 'A' + 1
131 case 'a' <= byteCount && byteCount <= 'z':
132 byteCount = byteCount - 'a' + 27
133 default:
134 return p.Errorf(0, "binary patch: invalid length byte")
135 }
136
137 // base85 encodes every 4 bytes into 5 characters, with up to 3 bytes of end padding
138 maxByteCount := len(seq) / 5 * 4
139 if byteCount > maxByteCount || byteCount < maxByteCount-3 {
140 return p.Errorf(0, "binary patch: incorrect byte count")
141 }
142
143 if err := base85Decode(buf[:byteCount], []byte(seq)); err != nil {
144 return p.Errorf(0, "binary patch: %v", err)
145 }
146 data.Write(buf[:byteCount])
147
148 if err := p.Next(); err != nil {
149 if err == io.EOF {
150 return p.Errorf(0, "binary patch: unexpected EOF")
151 }
152 return err
153 }
154 }
155
156 if err := inflateBinaryChunk(frag, &data); err != nil {
157 return p.Errorf(0, "binary patch: %v", err)
158 }
159
160 // consume the empty line that ended the fragment

Callers 3

ParseBinaryFragmentsMethod · 0.95
TestParseBinaryChunkFunction · 0.80

Calls 6

LineMethod · 0.95
ErrorfMethod · 0.95
NextMethod · 0.95
base85DecodeFunction · 0.85
inflateBinaryChunkFunction · 0.85
WriteMethod · 0.80

Tested by 2

TestParseBinaryChunkFunction · 0.64