-
Notifications
You must be signed in to change notification settings - Fork 683
/
reader.go
75 lines (66 loc) · 1.32 KB
/
reader.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
71
72
73
74
75
package dexec
import (
"bytes"
"fmt"
"io"
"os"
"unicode/utf8"
)
func fixupReader(o io.Reader, log func(string)) io.Reader {
if o == nil {
o = nilReader{}
}
if _, isFile := o.(*os.File); isFile {
return o
}
o = &loggingReader{
log: log,
reader: o,
}
return o
}
type nilReader struct{}
func (nilReader) Read(_ []byte) (int, error) { return 0, io.EOF }
type loggingReader struct {
log func(string)
reader io.Reader
}
func (l *loggingReader) Read(p []byte) (n int, err error) {
n, err = l.reader.Read(p)
toLog := p[:n]
for len(toLog) > 0 {
nl := bytes.IndexByte(toLog, '\n')
var line []byte
if nl < 0 {
line = toLog
toLog = nil
} else {
line = toLog[:nl+1]
toLog = toLog[nl+1:]
}
if utf8.Valid(line) {
if utf8.RuneCount(line) > 80 {
truncated := line
for utf8.RuneCount(truncated) > 80 {
_, size := utf8.DecodeLastRune(truncated)
truncated = truncated[:len(truncated)-size]
}
l.log(fmt.Sprintf("%q… (%d runes truncated)",
truncated,
utf8.RuneCount(line)-utf8.RuneCount(truncated)))
} else {
l.log(fmt.Sprintf("%q", line))
}
} else {
l.log(fmt.Sprintf("[...%d bytes of binary data...]", len(line)))
}
}
if err != nil {
if err == io.EOF {
l.log("EOF")
} else {
l.log(fmt.Sprintf("error = %v", err))
}
}
return n, err
}