status-go/vendor/github.com/pion/transport/replaydetector/fixedbig.go

79 lines
1.4 KiB
Go

package replaydetector
import (
"fmt"
)
// fixedBigInt is the fix-sized multi-word integer.
type fixedBigInt struct {
bits []uint64
n uint
msbMask uint64
}
// newFixedBigInt creates a new fix-sized multi-word int.
func newFixedBigInt(n uint) *fixedBigInt {
chunkSize := (n + 63) / 64
if chunkSize == 0 {
chunkSize = 1
}
return &fixedBigInt{
bits: make([]uint64, chunkSize),
n: n,
msbMask: (1 << (64 - n%64)) - 1,
}
}
// Lsh is the left shift operation.
func (s *fixedBigInt) Lsh(n uint) {
if n == 0 {
return
}
nChunk := int(n / 64)
nN := n % 64
for i := len(s.bits) - 1; i >= 0; i-- {
var carry uint64
if i-nChunk >= 0 {
carry = s.bits[i-nChunk] << nN
if i-nChunk-1 >= 0 {
carry |= s.bits[i-nChunk-1] >> (64 - nN)
}
}
s.bits[i] = (s.bits[i] << n) | carry
}
s.bits[len(s.bits)-1] &= s.msbMask
}
// Bit returns i-th bit of the fixedBigInt.
func (s *fixedBigInt) Bit(i uint) uint {
if i >= s.n {
return 0
}
chunk := i / 64
pos := i % 64
if s.bits[chunk]&(1<<pos) != 0 {
return 1
}
return 0
}
// SetBit sets i-th bit to 1.
func (s *fixedBigInt) SetBit(i uint) {
if i >= s.n {
return
}
chunk := i / 64
pos := i % 64
s.bits[chunk] |= 1 << pos
}
// String returns string representation of fixedBigInt.
func (s *fixedBigInt) String() string {
var out string
for i := len(s.bits) - 1; i >= 0; i-- {
out += fmt.Sprintf("%016X", s.bits[i])
}
return out
}