Book a Demo!
CoCalc Logo Icon
StoreFeaturesDocsShareSupportNewsAboutPoliciesSign UpSign In
alist-org
GitHub Repository: alist-org/alist
Path: blob/main/pkg/chanio/chanio.go
1560 views
1
package chanio
2
3
import (
4
"io"
5
"sync/atomic"
6
)
7
8
type ChanIO struct {
9
cl atomic.Bool
10
c chan []byte
11
buf []byte
12
}
13
14
func New() *ChanIO {
15
return &ChanIO{
16
cl: atomic.Bool{},
17
c: make(chan []byte),
18
buf: make([]byte, 0),
19
}
20
}
21
22
func (c *ChanIO) Read(p []byte) (int, error) {
23
if c.cl.Load() {
24
if len(c.buf) == 0 {
25
return 0, io.EOF
26
}
27
n := copy(p, c.buf)
28
if len(c.buf) > n {
29
c.buf = c.buf[n:]
30
} else {
31
c.buf = make([]byte, 0)
32
}
33
return n, nil
34
}
35
for len(c.buf) < len(p) && !c.cl.Load() {
36
c.buf = append(c.buf, <-c.c...)
37
}
38
n := copy(p, c.buf)
39
if len(c.buf) > n {
40
c.buf = c.buf[n:]
41
} else {
42
c.buf = make([]byte, 0)
43
}
44
return n, nil
45
}
46
47
func (c *ChanIO) Write(p []byte) (int, error) {
48
if c.cl.Load() {
49
return 0, io.ErrClosedPipe
50
}
51
c.c <- p
52
return len(p), nil
53
}
54
55
func (c *ChanIO) Close() error {
56
if c.cl.Load() {
57
return io.ErrClosedPipe
58
}
59
c.cl.Store(true)
60
close(c.c)
61
return nil
62
}
63
64