-
Notifications
You must be signed in to change notification settings - Fork 3
/
writer.go
134 lines (106 loc) · 1.95 KB
/
writer.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
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
134
package dos2unix
import "io"
// WriteFlusher combines the io.Writer interface with a buffer Flush method.
type WriteFlusher interface {
io.Writer
Flush() error
}
var cr = []byte{'\r'}
type dos2unixWriter struct {
io.Writer
lastCR bool
}
func (d *dos2unixWriter) Write(p []byte) (int, error) {
var n int
if d.lastCR && len(p) > 0 {
if p[0] != '\n' {
_, err := d.Writer.Write(cr)
if err != nil {
return 0, err
}
}
d.lastCR = false
}
for pos := 0; pos < len(p); pos++ {
if d.lastCR {
if p[pos] == '\n' {
if pos > 1 { // more than just \r\n
m, err := d.Writer.Write(p[:pos-1])
n += m
if err != nil {
return n, err
}
}
n++
p = p[pos:]
pos = 0
}
}
d.lastCR = p[pos] == '\r'
}
if len(p) > 0 {
if d.lastCR {
p = p[:len(p)-1]
n++
}
if len(p) > 0 {
m, err := d.Writer.Write(p)
n += m
if err != nil {
return n, err
}
}
}
return n, nil
}
func (d *dos2unixWriter) Flush() error {
if !d.lastCR {
return nil
}
d.lastCR = false
_, err := d.Writer.Write(cr)
return err
}
// DOS2UnixWriter wraps a writer to convert \r\n into \n. It is advisable to
// call the Flush method upon completion as a final \r may be buffered.
func DOS2UnixWriter(w io.Writer) WriteFlusher {
return &dos2unixWriter{
Writer: w,
}
}
type unix2dosWriter struct {
io.Writer
}
func (u unix2dosWriter) Write(p []byte) (int, error) {
var n int
for pos := 0; pos < len(p); pos++ {
if p[pos] == '\n' {
if pos > 0 {
m, err := u.Writer.Write(p[:pos])
n += m
if err != nil {
return n, err
}
p = p[pos:]
pos = 0
}
if _, err := u.Writer.Write(cr); err != nil {
return n, err
}
}
}
if len(p) > 0 {
m, err := u.Writer.Write(p)
n += m
if err != nil {
return n, err
}
}
return n, nil
}
// Unix2DOSWriter wraps a io.Writer to convert \n into \r\n.
func Unix2DOSWriter(w io.Writer) io.Writer {
return unix2dosWriter{
Writer: w,
}
}