vendor/github.com/gorilla/websocket/mask.go
changeset 242 2a9ec03fe5a1
child 260 445e01aede7e
equal deleted inserted replaced
241:e77dad242f4c 242:2a9ec03fe5a1
       
     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 }