-
Notifications
You must be signed in to change notification settings - Fork 0
/
Copy pathio_type_cover.go
157 lines (137 loc) · 3.3 KB
/
io_type_cover.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
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
package io
import (
"encoding/base64"
"encoding/hex"
"github.com/injoyai/conv"
"io"
"sync/atomic"
)
//=============================覆盖读写=============================
func NewCoverWriter(w io.Writer, handler func(p []byte) ([]byte, error)) *CoverWriter {
return &CoverWriter{
Writer: w,
Handler: handler,
}
}
// CoverWriter 覆盖写,写入经过handler处理后的数据
type CoverWriter struct {
io.Writer
Handler func(p []byte) ([]byte, error)
}
func (this *CoverWriter) Write(bs []byte) (n int, err error) {
if this.Handler != nil {
bs, err = this.Handler(bs)
if err != nil {
return 0, err
}
}
return this.Writer.Write(bs)
}
// WriteString 写入字符串,实现io.StringWriter
func (this *CoverWriter) WriteString(s string) (int, error) {
return this.Write([]byte(s))
}
// WriteHEX 写入16进制数据
func (this *CoverWriter) WriteHEX(s string) (int, error) {
bytes, err := hex.DecodeString(s)
if err != nil {
return 0, err
}
return this.Write(bytes)
}
// WriteBase64 写入base64数据
func (this *CoverWriter) WriteBase64(s string) (int, error) {
bytes, err := base64.StdEncoding.DecodeString(s)
if err != nil {
return 0, err
}
return this.Write(bytes)
}
// WriteAny 写入任意数据,根据conv转成字节
func (this *CoverWriter) WriteAny(any interface{}) (int, error) {
return this.Write(conv.Bytes(any))
}
// WriteSplit 写入字节,分片写入,例如udp需要写入字节小于(1500-20-8=1472)
func (this *CoverWriter) WriteSplit(p []byte, length int) (int, error) {
if length <= 0 {
return this.Write(p)
}
for len(p) > 0 {
var data []byte
if len(p) >= length {
data, p = p[:length], p[length:]
} else {
data, p = p, p[:0]
}
_, err := this.Write(data)
if err != nil {
return 0, err
}
}
return len(p), nil
}
// WriteReader io.Reader
func (this *CoverWriter) WriteReader(reader Reader) (int64, error) {
return Copy(this, reader)
}
// WriteChan 监听通道并写入
func (this *CoverWriter) WriteChan(c chan interface{}) (int64, error) {
var total int64
for data := range c {
n, err := this.Write(conv.Bytes(data))
if err != nil {
return 0, err
}
total += int64(n)
}
return total, nil
}
//===================================================
// CoverReader 覆盖读,返回经过handler处理后的数据
type CoverReader struct {
io.Reader
Handler func(p []byte) ([]byte, error)
}
func (this *CoverReader) Read(bs []byte) (n int, err error) {
n, err = this.Reader.Read(bs)
if err != nil {
return 0, err
}
if this.Handler != nil {
bs, err = this.Handler(bs)
if err != nil {
return 0, err
}
}
return
}
//===================================================
// CoverCloser 覆盖关闭,返回经过handler处理后的数据
type CoverCloser struct {
io.Closer
Handler func(err error)
closed uint32 //0是未关闭,1是关闭中,2是已关闭
}
func (this *CoverCloser) Close() error {
return this.CloseWithErr(ErrHandClose)
}
func (this *CoverCloser) CloseWithErr(err error) error {
if err == nil {
return nil
}
if this.Closed() {
return nil
}
if err := this.Closer.Close(); err != nil {
return err
}
defer atomic.StoreUint32(&this.closed, 1)
if this.Handler != nil {
this.Handler(err)
}
return nil
}
// Closed 是否已关闭
func (this *CoverCloser) Closed() bool {
return atomic.LoadUint32(&this.closed) > 0
}