|
|
@@ -22,20 +22,20 @@ func (c *StreamCipherReadWriteCloser) Read(p []byte) (n int, err error) {
|
|
22
|
22
|
|
|
23
|
23
|
// Write writes into connection.
|
|
24
|
24
|
func (c *StreamCipherReadWriteCloser) Write(p []byte) (int, error) {
|
|
25
|
|
- encrypted := make([]byte, len(p))
|
|
|
25
|
+ // This is to decrease an amount of allocations. Unfortunately, escape
|
|
|
26
|
+ // analysis in (at least Golang 1.10) is absolutely not perfect. For
|
|
|
27
|
+ // example, it understands that we want to have a slice locally, right?
|
|
|
28
|
+ // But since slice is effectively 2 ints + uintptr to [number]byte, the
|
|
|
29
|
+ // most heavyweight part is placed in heap.
|
|
|
30
|
+ buf := getBuffer()
|
|
|
31
|
+ defer putBuffer(buf)
|
|
|
32
|
+ buf.Grow(len(p))
|
|
|
33
|
+ buf.Write(p)
|
|
|
34
|
+
|
|
|
35
|
+ encrypted := buf.Bytes()
|
|
26
|
36
|
c.encryptor.XORKeyStream(encrypted, p)
|
|
27
|
|
- allWritten := 0
|
|
28
|
|
-
|
|
29
|
|
- for len(encrypted) > 0 {
|
|
30
|
|
- n, err := c.conn.Write(encrypted)
|
|
31
|
|
- allWritten += n
|
|
32
|
|
- if err != nil {
|
|
33
|
|
- return allWritten, err
|
|
34
|
|
- }
|
|
35
|
|
- encrypted = encrypted[n:]
|
|
36
|
|
- }
|
|
37
|
37
|
|
|
38
|
|
- return allWritten, nil
|
|
|
38
|
+ return c.conn.Write(encrypted)
|
|
39
|
39
|
}
|
|
40
|
40
|
|
|
41
|
41
|
// Close closes underlying connection.
|