-
-
Notifications
You must be signed in to change notification settings - Fork 302
/
iowrapper.go
99 lines (79 loc) · 2.26 KB
/
iowrapper.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
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
package mgutil
import (
"io"
"sync"
)
var (
_ io.Reader = (*IOWrapper)(nil)
_ io.Writer = (*IOWrapper)(nil)
_ io.Closer = (*IOWrapper)(nil)
_ io.Reader = (ReaderFunc)(nil)
_ io.Writer = (WriterFunc)(nil)
)
// IOWrapper implements various optional io interfaces.
// It delegates to the interface fields that are not nil
type IOWrapper struct {
// If Locker is not nil, all methods are called while holding the lock
Locker sync.Locker
// If Reader is not nil, it will be called to handle reads
Reader io.Reader
// If Writer is not nil, it will be called to handle writes
Writer io.Writer
// If Closer is not nil, it will be called to handle closes
Closer io.Closer
// If Flusher is not nil, it will be called to handle flushes
Flusher interface{ Flush() error }
}
// lockUnlock locks Locker if it's not nil and returns Locker.Unlock
// otherwise it returns a nop unlock function
func (iow *IOWrapper) lockUnlock() func() {
if mu := iow.Locker; mu != nil {
mu.Lock()
return mu.Unlock
}
return func() {}
}
// Read calls Reader.Read() if Reader is not nil
// otherwise it returns `0, io.EOF`
func (iow *IOWrapper) Read(p []byte) (int, error) {
defer iow.lockUnlock()()
if r := iow.Reader; r != nil {
return r.Read(p)
}
return 0, io.EOF
}
// Write calls Writer.Write() if Writer is not nil
// otherwise it returns `len(p), nil`
func (iow *IOWrapper) Write(p []byte) (int, error) {
defer iow.lockUnlock()()
if w := iow.Writer; w != nil {
return w.Write(p)
}
return len(p), nil
}
// Close calls Closer.Close() if Closer is not nil
// otherwise it returns `nil`
func (iow *IOWrapper) Close() error {
defer iow.lockUnlock()()
if c := iow.Closer; c != nil {
return c.Close()
}
return nil
}
// Flush calls Flushr.Flush() if Flusher is not nil
// otherwise it returns `nil`
func (iow *IOWrapper) Flush() error {
defer iow.lockUnlock()()
if f := iow.Flusher; f != nil {
return f.Flush()
}
return nil
}
// WriterFunc implements io.Writer using a function.
type WriterFunc func([]byte) (int, error)
// Write calls f(p)
func (f WriterFunc) Write(p []byte) (int, error) { return f(p) }
// ReaderFunc implements io.Reader using a function.
type ReaderFunc func([]byte) (int, error)
// Read calls f(p)
func (f ReaderFunc) Read(p []byte) (int, error) { return f(p) }