reflector.go/dht/bitmap.go

103 lines
1.7 KiB
Go
Raw Normal View History

2018-03-07 02:15:44 +01:00
package dht
import (
"encoding/hex"
"math/rand"
"strconv"
2018-03-08 01:49:33 +01:00
"github.com/zeebo/bencode"
2018-03-07 02:15:44 +01:00
)
type bitmap [nodeIDLength]byte
func (b bitmap) RawString() string {
return string(b[0:nodeIDLength])
}
func (b bitmap) Hex() string {
return hex.EncodeToString(b[0:nodeIDLength])
}
func (b bitmap) Equals(other bitmap) bool {
for k := range b {
if b[k] != other[k] {
return false
}
}
return true
}
func (b bitmap) Less(other interface{}) bool {
for k := range b {
if b[k] != other.(bitmap)[k] {
return b[k] < other.(bitmap)[k]
}
}
return false
}
func (b bitmap) Xor(other bitmap) bitmap {
var ret bitmap
for k := range b {
ret[k] = b[k] ^ other[k]
}
return ret
}
// PrefixLen returns the number of leading 0 bits
func (b bitmap) PrefixLen() (ret int) {
for i := range b {
for j := 0; j < 8; j++ {
if (b[i]>>uint8(7-j))&0x1 != 0 {
return i*8 + j
}
}
}
return nodeIDLength*8 - 1
}
2018-03-08 01:49:33 +01:00
func (b *bitmap) UnmarshalBencode(encoded []byte) error {
var str string
err := bencode.DecodeBytes(encoded, &str)
if err != nil {
return err
}
copy(b[:], str)
return nil
}
func (b bitmap) MarshalBencode() ([]byte, error) {
str := string(b[:])
return bencode.EncodeBytes(str)
}
2018-03-07 02:15:44 +01:00
func newBitmapFromBytes(data []byte) bitmap {
if len(data) != nodeIDLength {
panic("invalid bitmap of length " + strconv.Itoa(len(data)))
}
var bmp bitmap
copy(bmp[:], data)
return bmp
}
func newBitmapFromString(data string) bitmap {
return newBitmapFromBytes([]byte(data))
}
func newBitmapFromHex(hexStr string) bitmap {
decoded, err := hex.DecodeString(hexStr)
if err != nil {
panic(err)
}
return newBitmapFromBytes(decoded)
}
func newRandomBitmap() bitmap {
var id bitmap
for k := range id {
id[k] = uint8(rand.Intn(256))
}
return id
}