1
0
Fork 0
mirror of https://github.com/moby/moby.git synced 2022-11-09 12:21:53 -05:00

Add serialize/deserialize for sequence list

Signed-off-by: Alessandro Boch <aboch@docker.com>
This commit is contained in:
Alessandro Boch 2015-06-12 15:06:42 -07:00
parent 873ea8a224
commit 75443aaf72
3 changed files with 133 additions and 0 deletions

View file

@ -5,6 +5,8 @@ package bitseq
import (
"fmt"
"github.com/docker/libnetwork/netutils"
)
// Block Sequence constants
@ -74,6 +76,45 @@ func (s *Sequence) Equal(o *Sequence) bool {
return true
}
// ToByteArray converts the sequence into a byte array
// TODO (aboch): manage network/host order stuff
func (s *Sequence) ToByteArray() ([]byte, error) {
var bb []byte
p := s
for p != nil {
bb = append(bb, netutils.U32ToA(p.Block)...)
bb = append(bb, netutils.U32ToA(p.Count)...)
p = p.Next
}
return bb, nil
}
// FromByteArray construct the sequence from the byte array
// TODO (aboch): manage network/host order stuff
func (s *Sequence) FromByteArray(data []byte) error {
l := len(data)
if l%8 != 0 {
return fmt.Errorf("cannot deserialize byte sequence of lenght %d", l)
}
p := s
i := 0
for {
p.Block = netutils.ATo32(data[i : i+4])
p.Count = netutils.ATo32(data[i+4 : i+8])
i += 8
if i == l {
break
}
p.Next = &Sequence{}
p = p.Next
}
return nil
}
// GetFirstAvailable looks for the first unset bit in passed mask
func GetFirstAvailable(head *Sequence) (int, int) {
byteIndex := 0

View file

@ -331,3 +331,45 @@ func TestPushReservation(t *testing.T) {
}
}
}
func TestSerializeDeserialize(t *testing.T) {
s := &Sequence{
Block: 0xffffffff,
Count: 1,
Next: &Sequence{
Block: 0xFF000000,
Count: 1,
Next: &Sequence{
Block: 0xffffffff,
Count: 6,
Next: &Sequence{
Block: 0xffffffff,
Count: 1,
Next: &Sequence{
Block: 0xFF800000,
Count: 1,
Next: &Sequence{
Block: 0xffffffff,
Count: 6,
},
},
},
},
},
}
data, err := s.ToByteArray()
if err != nil {
t.Fatal(err)
}
r := &Sequence{}
err = r.FromByteArray(data)
if err != nil {
t.Fatal(err)
}
if !s.Equal(r) {
t.Fatalf("Sequences are different: \n%v\n%v", s, r)
}
}

View file

@ -168,3 +168,53 @@ func GenerateIfaceName(prefix string, len int) (string, error) {
}
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)
}