diff options
Diffstat (limited to 'vendor/github.com/pion/stun/xor.go')
-rw-r--r-- | vendor/github.com/pion/stun/xor.go | 62 |
1 files changed, 62 insertions, 0 deletions
diff --git a/vendor/github.com/pion/stun/xor.go b/vendor/github.com/pion/stun/xor.go new file mode 100644 index 0000000..34365eb --- /dev/null +++ b/vendor/github.com/pion/stun/xor.go @@ -0,0 +1,62 @@ +// Copyright 2013 The Go Authors. All rights reserved. +// Use of this source code is governed by a BSD-style +// license that can be found in the LICENSE file. + +package stun + +import ( + "runtime" + "unsafe" +) + +// #nosec +const wordSize = int(unsafe.Sizeof(uintptr(0))) + +var supportsUnaligned = runtime.GOARCH == "386" || runtime.GOARCH == "amd64" + +// fastXORBytes xors in bulk. It only works on architectures that +// support unaligned read/writes. +// +// #nosec +func fastXORBytes(dst, a, b []byte) int { + n := len(a) + if len(b) < n { + n = len(b) + } + + w := n / wordSize + if w > 0 { + dw := *(*[]uintptr)(unsafe.Pointer(&dst)) + aw := *(*[]uintptr)(unsafe.Pointer(&a)) + bw := *(*[]uintptr)(unsafe.Pointer(&b)) + for i := 0; i < w; i++ { + dw[i] = aw[i] ^ bw[i] + } + } + + for i := n - n%wordSize; i < n; i++ { + dst[i] = a[i] ^ b[i] + } + + return n +} + +func safeXORBytes(dst, a, b []byte) int { + n := len(a) + if len(b) < n { + n = len(b) + } + for i := 0; i < n; i++ { + dst[i] = a[i] ^ b[i] + } + return n +} + +// xorBytes xors the bytes in a and b. The destination is assumed to have enough +// space. Returns the number of bytes xor'd. +func xorBytes(dst, a, b []byte) int { + if supportsUnaligned { + return fastXORBytes(dst, a, b) + } + return safeXORBytes(dst, a, b) +} |