gtsocial-umbx

Unnamed repository; edit this file 'description' to name the repository.
Log | Files | Refs | README | LICENSE

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 }