/
hashwriter.go
70 lines (59 loc) · 1.09 KB
/
hashwriter.go
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
package cba
import (
"hash"
"io"
"log"
"os"
"path/filepath"
"time"
)
type HashWriter struct {
start time.Time
hasher hash.Hash
dest *os.File
cache *Store
size int
}
func (st *HashWriter) Sum() string {
return string(st.hasher.Sum(nil))
}
func (st *HashWriter) Write(p []byte) (n int, err error) {
n, err = st.dest.Write(p)
st.hasher.Write(p[:n])
st.size += n
return n, err
}
func (st *HashWriter) WriteClose(p []byte) (err error) {
_, err = st.Write(p)
if err != nil {
return err
}
err = st.Close()
return err
}
func (st *HashWriter) CopyClose(input io.Reader, size int64) error {
_, err := io.CopyN(st, input, size)
if err != nil {
return err
}
err = st.Close()
return err
}
func (st *HashWriter) Close() error {
st.dest.Chmod(0444)
err := st.dest.Close()
if err != nil {
return err
}
src := st.dest.Name()
dir, _ := filepath.Split(src)
sum := st.Sum()
sumpath := HashPath(dir, sum)
err = os.Rename(src, sumpath)
if err != nil {
log.Fatal("Rename failed", err)
}
dt := time.Now().Sub(st.start)
st.cache.AddTiming("Save", st.size, dt)
return err
}