equal
deleted
inserted
replaced
|
1 // Copyright 2016 The Gorilla WebSocket Authors. All rights reserved. Use of |
|
2 // this source code is governed by a BSD-style license that can be found in the |
|
3 // LICENSE file. |
|
4 |
|
5 // +build !appengine |
|
6 |
|
7 package websocket |
|
8 |
|
9 import "unsafe" |
|
10 |
|
11 const wordSize = int(unsafe.Sizeof(uintptr(0))) |
|
12 |
|
13 func maskBytes(key [4]byte, pos int, b []byte) int { |
|
14 // Mask one byte at a time for small buffers. |
|
15 if len(b) < 2*wordSize { |
|
16 for i := range b { |
|
17 b[i] ^= key[pos&3] |
|
18 pos++ |
|
19 } |
|
20 return pos & 3 |
|
21 } |
|
22 |
|
23 // Mask one byte at a time to word boundary. |
|
24 if n := int(uintptr(unsafe.Pointer(&b[0]))) % wordSize; n != 0 { |
|
25 n = wordSize - n |
|
26 for i := range b[:n] { |
|
27 b[i] ^= key[pos&3] |
|
28 pos++ |
|
29 } |
|
30 b = b[n:] |
|
31 } |
|
32 |
|
33 // Create aligned word size key. |
|
34 var k [wordSize]byte |
|
35 for i := range k { |
|
36 k[i] = key[(pos+i)&3] |
|
37 } |
|
38 kw := *(*uintptr)(unsafe.Pointer(&k)) |
|
39 |
|
40 // Mask one word at a time. |
|
41 n := (len(b) / wordSize) * wordSize |
|
42 for i := 0; i < n; i += wordSize { |
|
43 *(*uintptr)(unsafe.Pointer(uintptr(unsafe.Pointer(&b[0])) + uintptr(i))) ^= kw |
|
44 } |
|
45 |
|
46 // Mask one byte at a time for remaining bytes. |
|
47 b = b[n:] |
|
48 for i := range b { |
|
49 b[i] ^= key[pos&3] |
|
50 pos++ |
|
51 } |
|
52 |
|
53 return pos & 3 |
|
54 } |