...
Source file src/pkg/cmd/internal/buildid/rewrite.go
1
2
3
4
5 package buildid
6
7 import (
8 "bytes"
9 "crypto/sha256"
10 "fmt"
11 "io"
12 )
13
14
15
16
17
18
19 func FindAndHash(r io.Reader, id string, bufSize int) (matches []int64, hash [32]byte, err error) {
20 if bufSize == 0 {
21 bufSize = 31 * 1024
22 }
23 if len(id) > bufSize {
24 return nil, [32]byte{}, fmt.Errorf("buildid.FindAndHash: buffer too small")
25 }
26 zeros := make([]byte, len(id))
27 idBytes := []byte(id)
28
29
30
31
32
33
34
35
36 tiny := (len(id) + 127) &^ 127
37 buf := make([]byte, tiny+bufSize)
38 h := sha256.New()
39 start := tiny
40 for offset := int64(0); ; {
41
42
43
44 n, err := io.ReadFull(r, buf[tiny:])
45 if err != io.ErrUnexpectedEOF && err != io.EOF && err != nil {
46 return nil, [32]byte{}, err
47 }
48
49
50 for {
51 i := bytes.Index(buf[start:tiny+n], idBytes)
52 if i < 0 {
53 break
54 }
55 matches = append(matches, offset+int64(start+i-tiny))
56 h.Write(buf[start : start+i])
57 h.Write(zeros)
58 start += i + len(id)
59 }
60 if n < bufSize {
61
62 h.Write(buf[start : tiny+n])
63 break
64 }
65
66
67
68
69 if start < len(buf)-tiny {
70 h.Write(buf[start : len(buf)-tiny])
71 start = len(buf) - tiny
72 }
73
74
75 copy(buf[0:], buf[bufSize:])
76 start -= bufSize
77 offset += int64(bufSize)
78 }
79 h.Sum(hash[:0])
80 return matches, hash, nil
81 }
82
83 func Rewrite(w io.WriterAt, pos []int64, id string) error {
84 b := []byte(id)
85 for _, p := range pos {
86 if _, err := w.WriteAt(b, p); err != nil {
87 return err
88 }
89 }
90 return nil
91 }
92
View as plain text