4
4
"bytes"
5
5
"encoding/binary"
6
6
"io"
7
+ "sync"
7
8
8
9
"github.com/ovh/symmecrypt"
9
10
_ "github.com/ovh/symmecrypt/keyloader"
@@ -42,29 +43,54 @@ func (k key) DecryptPipe(r io.Reader, w io.Writer, extra ...[]byte) error {
42
43
return nil
43
44
}
44
45
46
+ var buffers = sync.Pool {
47
+ New : func () interface {} {
48
+ return new (bytes.Buffer )
49
+ },
50
+ }
51
+
52
+ func getBuffer () (* bytes.Buffer , error ) {
53
+ if b , ok := buffers .Get ().(* bytes.Buffer ); ok {
54
+ b .Reset ()
55
+ return b , nil
56
+ }
57
+
58
+ panic ("buffers is not of type *bytes.Buffer" )
59
+ }
60
+
61
+ func putBuffer (buf * bytes.Buffer ) {
62
+ buffers .Put (buf )
63
+ }
64
+
45
65
var _ io.WriteCloser = new (chunksWriter )
46
66
47
67
type chunksWriter struct {
48
68
destination io.Writer
49
69
k symmecrypt.Key
50
70
extras [][]byte
51
71
chunkSize int
52
- currentChunkWriter * bytes.Buffer
72
+ buf * bytes.Buffer
53
73
currentChunkBytesWritten int
54
74
}
55
75
56
76
func (w * chunksWriter ) encryptCurrentChunk () error {
57
- if w .currentChunkWriter == nil && w .currentChunkBytesWritten == 0 {
77
+ if w .buf == nil && w .currentChunkBytesWritten == 0 {
58
78
return nil
59
79
}
60
- currentChunk := w . currentChunkWriter . Bytes ()
80
+
61
81
// first step: encrypt the chunks
62
- btes , err := w .k .Encrypt (currentChunk , w .extras ... )
82
+ btes , err := w .k .Encrypt (w . buf . Bytes () , w .extras ... )
63
83
if err != nil {
64
84
return err
65
85
}
66
86
67
87
// then write into the destination writer the len of the encrypted chunks
88
+ headerBytes , err := getBuffer ()
89
+ if err != nil {
90
+ return err
91
+ }
92
+ defer putBuffer (headerBytes )
93
+
68
94
headerBuf := make ([]byte , binary .MaxVarintLen32 )
69
95
binary .PutUvarint (headerBuf , uint64 (len (btes )))
70
96
if _ , err := w .destination .Write (headerBuf ); err != nil {
@@ -76,7 +102,8 @@ func (w *chunksWriter) encryptCurrentChunk() error {
76
102
77
103
// finally reset the current chunk
78
104
w .currentChunkBytesWritten = 0
79
- w .currentChunkWriter = nil
105
+ putBuffer (w .buf )
106
+ w .buf = nil
80
107
81
108
return err
82
109
}
@@ -85,8 +112,13 @@ func (w *chunksWriter) Write(p []byte) (int, error) {
85
112
if len (p ) == 0 {
86
113
return len (p ), nil
87
114
}
88
- if w .currentChunkWriter == nil {
89
- w .currentChunkWriter = new (bytes.Buffer )
115
+ if w .buf == nil {
116
+ chunkWriter , err := getBuffer ()
117
+ if err != nil {
118
+ return 0 , err
119
+ }
120
+
121
+ w .buf = chunkWriter
90
122
w .currentChunkBytesWritten = 0
91
123
}
92
124
@@ -97,7 +129,7 @@ func (w *chunksWriter) Write(p []byte) (int, error) {
97
129
}
98
130
99
131
if w .currentChunkBytesWritten + len (p ) == w .chunkSize {
100
- n , err := w .currentChunkWriter .Write (p )
132
+ n , err := w .buf .Write (p )
101
133
if err != nil {
102
134
return n , err
103
135
}
@@ -110,7 +142,7 @@ func (w *chunksWriter) Write(p []byte) (int, error) {
110
142
111
143
x := w .chunkSize - w .currentChunkBytesWritten
112
144
if len (p ) < x {
113
- n , err := w .currentChunkWriter .Write (p )
145
+ n , err := w .buf .Write (p )
114
146
w .currentChunkBytesWritten += int (n )
115
147
return n , err
116
148
} else {
@@ -176,19 +208,29 @@ func NewReader(r io.Reader, k symmecrypt.Key, chunkSize int, extras ...[]byte) i
176
208
}
177
209
178
210
func (r * chunksReader ) readNewChunk () error {
211
+ headerBtes , err := getBuffer ()
212
+ if err != nil {
213
+ return err
214
+ }
215
+ defer putBuffer (headerBtes )
216
+
179
217
// read the chunksize
180
- var headerBtes = new (bytes.Buffer )
181
218
if _ , err := io .CopyN (headerBtes , r .src , binary .MaxVarintLen32 ); err != nil {
182
219
return err
183
220
}
184
221
185
- n , err := binary .ReadUvarint (bytes . NewReader ( headerBtes . Bytes ()) ) // READ THE HEADER BUFFER
222
+ n , err := binary .ReadUvarint (headerBtes ) // READ THE HEADER BUFFER
186
223
if err != nil {
187
224
return err
188
225
}
189
226
190
227
// read the chunk content
191
- var btsBuff = new (bytes.Buffer )
228
+ btsBuff , err := getBuffer ()
229
+ if err != nil {
230
+ return err
231
+ }
232
+ defer putBuffer (btsBuff )
233
+
192
234
if _ , err := io .CopyN (btsBuff , r .src , int64 (n )); err != nil && err != io .EOF {
193
235
return err
194
236
}
0 commit comments