-
Notifications
You must be signed in to change notification settings - Fork 38
/
Copy pathbytes.go
171 lines (156 loc) · 4.09 KB
/
bytes.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
158
159
160
161
162
163
164
165
166
167
168
169
170
171
package dry
import (
"bytes"
"compress/flate"
"compress/gzip"
"crypto/md5" //#nosec
"encoding/base64"
"encoding/hex"
"fmt"
"io"
"strings"
)
func BytesReader(data interface{}) io.Reader {
switch s := data.(type) {
case io.Reader:
return s
case []byte:
return bytes.NewReader(s)
case string:
return strings.NewReader(s)
case fmt.Stringer:
return strings.NewReader(s.String())
case error:
return strings.NewReader(s.Error())
}
return nil
}
func BytesMD5(data string) string {
hash := md5.New() //#nosec
hash.Write([]byte(data))
return fmt.Sprintf("%x", hash.Sum(nil))
}
func BytesEncodeBase64(str string) string {
return base64.StdEncoding.EncodeToString([]byte(str))
}
func BytesDecodeBase64(base64Str string) string {
result, _ := base64.StdEncoding.DecodeString(base64Str)
return string(result)
}
func BytesEncodeHex(str string) string {
return hex.EncodeToString([]byte(str))
}
func BytesDecodeHex(hexStr string) string {
result, _ := hex.DecodeString(hexStr)
return string(result)
}
func BytesDeflate(uncompressed []byte) (compressed []byte) {
var buf bytes.Buffer
writer := Deflate.GetWriter(&buf)
_, err := writer.Write(uncompressed)
if err != nil {
panic(err)
}
Deflate.ReturnWriter(writer)
return buf.Bytes()
}
func BytesInflate(compressed []byte) (uncompressed []byte) {
reader := flate.NewReader(bytes.NewBuffer(compressed))
result, _ := io.ReadAll(reader)
return result
}
func BytesGzip(uncompressed []byte) (compressed []byte) {
var buf bytes.Buffer
writer := Gzip.GetWriter(&buf)
_, err := writer.Write(uncompressed)
if err != nil {
panic(err)
}
Gzip.ReturnWriter(writer)
return buf.Bytes()
}
func BytesUnGzip(compressed []byte) (uncompressed []byte) {
reader, err := gzip.NewReader(bytes.NewBuffer(compressed))
if err != nil {
return nil
}
result, _ := io.ReadAll(reader)
return result
}
// BytesHead returns at most numLines from data starting at the beginning.
// A slice of the remaining data is returned as rest.
// \n is used to detect line ends, a preceding \r will be stripped away.
// BytesHead resembles the Unix head command.
func BytesHead(data []byte, numLines int) (lines []string, rest []byte) {
if numLines <= 0 {
panic("numLines must be greater than zero")
}
lines = make([]string, 0, numLines)
begin := 0
for i := range data {
if data[i] == '\n' {
end := i
if i > 0 && data[i-1] == '\r' {
end--
}
lines = append(lines, string(data[begin:end]))
begin = i + 1
if len(lines) == numLines {
break
}
}
}
if len(lines) != numLines {
lines = append(lines, string(data[begin:]))
begin = len(data)
}
return lines, data[begin:]
}
// BytesTail returns at most numLines from the end of data.
// A slice of the remaining data before lines is returned as rest.
// \n is used to detect line ends, a preceding \r will be stripped away.
// BytesTail resembles the Unix tail command.
func BytesTail(data []byte, numLines int) (lines []string, rest []byte) {
if numLines <= 0 {
panic("numLines must be greater than zero")
}
lines = make([]string, 0, numLines)
end := len(data)
for i := len(data) - 1; i >= 0; i-- {
if data[i] == '\n' {
begin := i
if end < len(data) && data[end-1] == '\r' {
end--
}
lines = append(lines, string(data[begin+1:end]))
end = begin
if len(lines) == numLines {
break
}
}
}
if len(lines) != numLines {
lines = append(lines, string(data[:end]))
end = 0
}
return lines, data[:end]
}
// BytesMap maps a function on each element of a slice of bytes.
func BytesMap(f func(byte) byte, data []byte) []byte {
size := len(data)
result := make([]byte, size, size)
for i := 0; i < size; i++ {
result[i] = f(data[i])
}
return result
}
// BytesFilter filters out all bytes where the function does not return true.
func BytesFilter(f func(byte) bool, data []byte) []byte {
result := make([]byte, 0, 0)
for _, element := range data {
if f(element) {
result = append(result, element)
}
}
return result
}