-
Notifications
You must be signed in to change notification settings - Fork 2
Expand file tree
/
Copy pathCRLFWriter.go
More file actions
133 lines (114 loc) · 2.27 KB
/
Copy pathCRLFWriter.go
File metadata and controls
133 lines (114 loc) · 2.27 KB
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
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
package terminal
import (
"bytes"
"io"
"strings"
"sync"
)
type CRLFWriter struct {
// Out is the underlying writer to write to.
Out io.Writer
}
func (w *CRLFWriter) Write(buf []byte) (n int, err error) {
return CRLFWrite(w.Out, buf)
}
func CRLFWrite(out io.Writer, buf []byte) (n int, err error) {
// Somewhat copied from x/term's writeWithCRLF
for len(buf) > 0 {
i := bytes.IndexByte(buf, '\n')
todo := len(buf)
if i >= 0 {
todo = i
}
var nn int
nn, err = out.Write(buf[:todo])
n += nn
if err != nil {
return n, err
}
buf = buf[todo:]
if i >= 0 {
if _, err = out.Write([]byte{'\r', '\n'}); err != nil {
return n, err
}
n++
buf = buf[1:]
}
}
// Auto flush
if flusher, ok := out.(FlushWriter); ok {
err = flusher.Flush()
}
return n, err
}
func (w *CRLFWriter) Flush() error {
// flush already done at the end of Write.
return nil
}
type FlushWriter interface {
io.Writer
Flush() error
}
type Bufio interface {
FlushWriter
io.StringWriter
io.ByteWriter
WriteRune(r rune) (n int, err error)
}
// SyncWriter is a threadsafe wrapper around a most of the APIs of bufio.Writer.
type SyncWriter struct {
// Out is the underlying writer to write to.
Out Bufio
// mu protects access to the Out writer.
mu sync.Mutex
}
func (w *SyncWriter) Write(buf []byte) (n int, err error) {
w.mu.Lock()
n, err = w.Out.Write(buf)
w.mu.Unlock()
return n, err
}
func (w *SyncWriter) Flush() error {
w.mu.Lock()
err := w.Out.Flush()
w.mu.Unlock()
return err
}
func (w *SyncWriter) WriteString(s string) (n int, err error) {
w.mu.Lock()
n, err = w.Out.WriteString(s)
w.mu.Unlock()
return n, err
}
func (w *SyncWriter) WriteByte(c byte) error {
w.mu.Lock()
err := w.Out.WriteByte(c)
w.mu.Unlock()
return err
}
func (w *SyncWriter) WriteRune(r rune) (n int, err error) {
w.mu.Lock()
n, err = w.Out.WriteRune(r)
w.mu.Unlock()
return n, err
}
// Lock: Shares the underlying lock.
func (w *SyncWriter) Lock() {
w.mu.Lock()
}
// Unlock: Shares the underlying lock.
func (w *SyncWriter) Unlock() {
w.mu.Unlock()
}
type FlushableStringBuilder struct {
strings.Builder
}
func (b *FlushableStringBuilder) Flush() error {
return nil
}
type FlushableBytesBuffer struct {
bytes.Buffer
}
func (b *FlushableBytesBuffer) Flush() error {
return nil
}