Support VarLong encode/decode
This commit is contained in:
@ -8,15 +8,15 @@ import (
|
|||||||
var VarInts = []VarInt{0, 1, 2, 127, 128, 255, 2147483647, -1, -2147483648}
|
var VarInts = []VarInt{0, 1, 2, 127, 128, 255, 2147483647, -1, -2147483648}
|
||||||
|
|
||||||
var PackedVarInts = [][]byte{
|
var PackedVarInts = [][]byte{
|
||||||
[]byte{0x00},
|
{0x00},
|
||||||
[]byte{0x01},
|
{0x01},
|
||||||
[]byte{0x02},
|
{0x02},
|
||||||
[]byte{0x7f},
|
{0x7f},
|
||||||
[]byte{0x80, 0x01},
|
{0x80, 0x01},
|
||||||
[]byte{0xff, 0x01},
|
{0xff, 0x01},
|
||||||
[]byte{0xff, 0xff, 0xff, 0xff, 0x07},
|
{0xff, 0xff, 0xff, 0xff, 0x07},
|
||||||
[]byte{0xff, 0xff, 0xff, 0xff, 0x0f},
|
{0xff, 0xff, 0xff, 0xff, 0x0f},
|
||||||
[]byte{0x80, 0x80, 0x80, 0x80, 0x08},
|
{0x80, 0x80, 0x80, 0x80, 0x08},
|
||||||
}
|
}
|
||||||
|
|
||||||
func TestPackVarInt(t *testing.T) {
|
func TestPackVarInt(t *testing.T) {
|
||||||
@ -39,24 +39,38 @@ func TestUnpackVarInt(t *testing.T) {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// func TestPositionPack(t *testing.T) {
|
var VarLongs = []VarLong{0, 1, 2, 127, 128, 255, 2147483647, 9223372036854775807, -1, -2147483648, -9223372036854775808}
|
||||||
// // This test is not good.
|
|
||||||
|
|
||||||
// for x := -33554432; x < 33554432; x += 55443 {
|
var PackedVarLongs = [][]byte{
|
||||||
// for y := -2048; y < 2048; y += 48 {
|
{0x00},
|
||||||
// for z := -33554432; z < 33554432; z += 55443 {
|
{0x01},
|
||||||
// var (
|
{0x02},
|
||||||
// pos1 Position
|
{0x7f},
|
||||||
// pos2 = Position{x, y, z}
|
{0x80, 0x01},
|
||||||
// )
|
{0xff, 0x01},
|
||||||
// if err := pos1.Decode(bytes.NewReader(pos2.Encode())); err != nil {
|
{0xff, 0xff, 0xff, 0xff, 0x07},
|
||||||
// t.Errorf("Position decode fail: %v", err)
|
{0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0x7f},
|
||||||
// }
|
{0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0x01},
|
||||||
|
{0x80, 0x80, 0x80, 0x80, 0xf8, 0xff, 0xff, 0xff, 0xff, 0x01},
|
||||||
|
{0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x01},
|
||||||
|
}
|
||||||
|
|
||||||
// if pos1 != pos2 {
|
func TestPackVarLong(t *testing.T) {
|
||||||
// t.Errorf("cannot pack %v", pos2)
|
for i, v := range VarLongs {
|
||||||
// }
|
p := v.Encode()
|
||||||
// }
|
if !bytes.Equal(p, PackedVarLongs[i]) {
|
||||||
// }
|
t.Errorf("pack long %d should be \"% x\", get \"% x\"", v, PackedVarLongs[i], p)
|
||||||
// }
|
}
|
||||||
// }
|
}
|
||||||
|
}
|
||||||
|
func TestUnpackVarLong(t *testing.T) {
|
||||||
|
for i, v := range PackedVarLongs {
|
||||||
|
var vi VarLong
|
||||||
|
if err := vi.Decode(bytes.NewReader(v)); err != nil {
|
||||||
|
t.Errorf("unpack \"% x\" error: %v", v, err)
|
||||||
|
}
|
||||||
|
if vi != VarLongs[i] {
|
||||||
|
t.Errorf("unpack \"% x\" should be %d, get %d", v, VarLongs[i], vi)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
@ -1,6 +1,7 @@
|
|||||||
package packet
|
package packet
|
||||||
|
|
||||||
import (
|
import (
|
||||||
|
"errors"
|
||||||
"github.com/google/uuid"
|
"github.com/google/uuid"
|
||||||
"io"
|
"io"
|
||||||
"math"
|
"math"
|
||||||
@ -268,7 +269,7 @@ func (v VarInt) Encode() (vi []byte) {
|
|||||||
//Decode a VarInt
|
//Decode a VarInt
|
||||||
func (v *VarInt) Decode(r DecodeReader) error {
|
func (v *VarInt) Decode(r DecodeReader) error {
|
||||||
var n uint32
|
var n uint32
|
||||||
for i := 0; i < 5; i++ { //读数据前的长度标记
|
for i := 0; ; i++ { //读数据前的长度标记
|
||||||
sec, err := r.ReadByte()
|
sec, err := r.ReadByte()
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return err
|
return err
|
||||||
@ -278,6 +279,8 @@ func (v *VarInt) Decode(r DecodeReader) error {
|
|||||||
|
|
||||||
if sec&0x80 == 0 {
|
if sec&0x80 == 0 {
|
||||||
break
|
break
|
||||||
|
} else if i > 5 {
|
||||||
|
return errors.New("VarInt is too big")
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -285,6 +288,45 @@ func (v *VarInt) Decode(r DecodeReader) error {
|
|||||||
return nil
|
return nil
|
||||||
}
|
}
|
||||||
|
|
||||||
|
//Encode a VarLong
|
||||||
|
func (v VarLong) Encode() (vi []byte) {
|
||||||
|
num := uint64(v)
|
||||||
|
for {
|
||||||
|
b := num & 0x7F
|
||||||
|
num >>= 7
|
||||||
|
if num != 0 {
|
||||||
|
b |= 0x80
|
||||||
|
}
|
||||||
|
vi = append(vi, byte(b))
|
||||||
|
if num == 0 {
|
||||||
|
break
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return
|
||||||
|
}
|
||||||
|
|
||||||
|
//Decode a VarLong
|
||||||
|
func (v *VarLong) Decode(r DecodeReader) error {
|
||||||
|
var n uint64
|
||||||
|
for i := 0; ; i++ { //读数据前的长度标记
|
||||||
|
sec, err := r.ReadByte()
|
||||||
|
if err != nil {
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
|
||||||
|
n |= uint64(sec&0x7F) << uint64(7*i)
|
||||||
|
|
||||||
|
if sec&0x80 == 0 {
|
||||||
|
break
|
||||||
|
} else if i > 10 {
|
||||||
|
return errors.New("VarInt is too big")
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
*v = VarLong(n)
|
||||||
|
return nil
|
||||||
|
}
|
||||||
|
|
||||||
//Encode a Position
|
//Encode a Position
|
||||||
func (p Position) Encode() []byte {
|
func (p Position) Encode() []byte {
|
||||||
b := make([]byte, 8)
|
b := make([]byte, 8)
|
||||||
|
Reference in New Issue
Block a user