mask.go (1176B)
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 //go:build !appengine 6 // +build !appengine 7 8 package websocket 9 10 import "unsafe" 11 12 const wordSize = int(unsafe.Sizeof(uintptr(0))) 13 14 func maskBytes(key [4]byte, pos int, b []byte) int { 15 // Mask one byte at a time for small buffers. 16 if len(b) < 2*wordSize { 17 for i := range b { 18 b[i] ^= key[pos&3] 19 pos++ 20 } 21 return pos & 3 22 } 23 24 // Mask one byte at a time to word boundary. 25 if n := int(uintptr(unsafe.Pointer(&b[0]))) % wordSize; n != 0 { 26 n = wordSize - n 27 for i := range b[:n] { 28 b[i] ^= key[pos&3] 29 pos++ 30 } 31 b = b[n:] 32 } 33 34 // Create aligned word size key. 35 var k [wordSize]byte 36 for i := range k { 37 k[i] = key[(pos+i)&3] 38 } 39 kw := *(*uintptr)(unsafe.Pointer(&k)) 40 41 // Mask one word at a time. 42 n := (len(b) / wordSize) * wordSize 43 for i := 0; i < n; i += wordSize { 44 *(*uintptr)(unsafe.Pointer(uintptr(unsafe.Pointer(&b[0])) + uintptr(i))) ^= kw 45 } 46 47 // Mask one byte at a time for remaining bytes. 48 b = b[n:] 49 for i := range b { 50 b[i] ^= key[pos&3] 51 pos++ 52 } 53 54 return pos & 3 55 }