network byte order to bitseq serializer

Signed-off-by: Alessandro Boch <aboch@docker.com>
This commit is contained in:
Alessandro Boch 2015-06-18 19:14:03 -07:00
parent 8b6a15795b
commit e5842be694
5 changed files with 17 additions and 62 deletions

View File

@ -4,11 +4,11 @@
package bitseq package bitseq
import ( import (
"encoding/binary"
"fmt" "fmt"
"sync" "sync"
"github.com/docker/libnetwork/datastore" "github.com/docker/libnetwork/datastore"
"github.com/docker/libnetwork/netutils"
) )
// Block Sequence constants // Block Sequence constants
@ -134,14 +134,15 @@ func (s *Sequence) Equal(o *Sequence) bool {
} }
// ToByteArray converts the sequence into a byte array // ToByteArray converts the sequence into a byte array
// TODO (aboch): manage network/host order stuff
func (s *Sequence) ToByteArray() ([]byte, error) { func (s *Sequence) ToByteArray() ([]byte, error) {
var bb []byte var bb []byte
p := s p := s
for p != nil { for p != nil {
bb = append(bb, netutils.U32ToA(p.Block)...) b := make([]byte, 8)
bb = append(bb, netutils.U32ToA(p.Count)...) binary.BigEndian.PutUint32(b[0:], p.Block)
binary.BigEndian.PutUint32(b[4:], p.Count)
bb = append(bb, b...)
p = p.Next p = p.Next
} }
@ -149,7 +150,6 @@ func (s *Sequence) ToByteArray() ([]byte, error) {
} }
// FromByteArray construct the sequence from the byte array // FromByteArray construct the sequence from the byte array
// TODO (aboch): manage network/host order stuff
func (s *Sequence) FromByteArray(data []byte) error { func (s *Sequence) FromByteArray(data []byte) error {
l := len(data) l := len(data)
if l%8 != 0 { if l%8 != 0 {
@ -159,8 +159,8 @@ func (s *Sequence) FromByteArray(data []byte) error {
p := s p := s
i := 0 i := 0
for { for {
p.Block = netutils.ATo32(data[i : i+4]) p.Block = binary.BigEndian.Uint32(data[i : i+4])
p.Count = netutils.ATo32(data[i+4 : i+8]) p.Count = binary.BigEndian.Uint32(data[i+4 : i+8])
i += 8 i += 8
if i == l { if i == l {
break break
@ -229,12 +229,12 @@ func (h *Handle) Destroy() {
// ToByteArray converts this handle's data into a byte array // ToByteArray converts this handle's data into a byte array
func (h *Handle) ToByteArray() ([]byte, error) { func (h *Handle) ToByteArray() ([]byte, error) {
ba := make([]byte, 8)
h.Lock() h.Lock()
defer h.Unlock() defer h.Unlock()
copy(ba[0:4], netutils.U32ToA(h.bits)) ba := make([]byte, 8)
copy(ba[4:8], netutils.U32ToA(h.unselected)) binary.BigEndian.PutUint32(ba[0:], h.bits)
binary.BigEndian.PutUint32(ba[4:], h.unselected)
bm, err := h.head.ToByteArray() bm, err := h.head.ToByteArray()
if err != nil { if err != nil {
return nil, fmt.Errorf("failed to serialize head: %s", err.Error()) return nil, fmt.Errorf("failed to serialize head: %s", err.Error())
@ -258,8 +258,8 @@ func (h *Handle) FromByteArray(ba []byte) error {
h.Lock() h.Lock()
h.head = nh h.head = nh
h.bits = netutils.ATo32(ba[0:4]) h.bits = binary.BigEndian.Uint32(ba[0:4])
h.unselected = netutils.ATo32(ba[4:8]) h.unselected = binary.BigEndian.Uint32(ba[4:8])
h.Unlock() h.Unlock()
return nil return nil

View File

@ -2,6 +2,8 @@ package bitseq
import ( import (
"testing" "testing"
_ "github.com/docker/libnetwork/netutils"
) )
func TestSequenceGetAvailableBit(t *testing.T) { func TestSequenceGetAvailableBit(t *testing.T) {

View File

@ -2,6 +2,8 @@ package idm
import ( import (
"testing" "testing"
_ "github.com/docker/libnetwork/netutils"
) )
func TestNew(t *testing.T) { func TestNew(t *testing.T) {

View File

@ -7,6 +7,7 @@ import (
"time" "time"
"github.com/docker/libnetwork/bitseq" "github.com/docker/libnetwork/bitseq"
_ "github.com/docker/libnetwork/netutils"
) )
func getAllocator(t *testing.T, subnet *net.IPNet) *Allocator { func getAllocator(t *testing.T, subnet *net.IPNet) *Allocator {

View File

@ -180,53 +180,3 @@ func GenerateIfaceName(prefix string, len int) (string, error) {
} }
return "", types.InternalErrorf("could not generate interface name") return "", types.InternalErrorf("could not generate interface name")
} }
func byteArrayToInt(array []byte, numBytes int) uint64 {
if numBytes <= 0 || numBytes > 8 {
panic("Invalid argument")
}
num := 0
for i := 0; i <= len(array)-1; i++ {
num += int(array[len(array)-1-i]) << uint(i*8)
}
return uint64(num)
}
// ATo64 converts a byte array into a uint32
func ATo64(array []byte) uint64 {
return byteArrayToInt(array, 8)
}
// ATo32 converts a byte array into a uint32
func ATo32(array []byte) uint32 {
return uint32(byteArrayToInt(array, 4))
}
// ATo16 converts a byte array into a uint16
func ATo16(array []byte) uint16 {
return uint16(byteArrayToInt(array, 2))
}
func intToByteArray(val uint64, numBytes int) []byte {
array := make([]byte, numBytes)
for i := numBytes - 1; i >= 0; i-- {
array[i] = byte(val & 0xff)
val = val >> 8
}
return array
}
// U64ToA converts a uint64 to a byte array
func U64ToA(val uint64) []byte {
return intToByteArray(uint64(val), 8)
}
// U32ToA converts a uint64 to a byte array
func U32ToA(val uint32) []byte {
return intToByteArray(uint64(val), 4)
}
// U16ToA converts a uint64 to a byte array
func U16ToA(val uint16) []byte {
return intToByteArray(uint64(val), 2)
}