msgpack-go

Message Pack Encoder/Decoder for Golang
git clone git://git.lair.cx/msgpack-go
Log | Files | Refs | LICENSE

msgpack_test.go (7280B)


      1 package msgpack
      2 
      3 import (
      4 	"bytes"
      5 	"fmt"
      6 	"time"
      7 
      8 	_ "embed"
      9 )
     10 
     11 //go:embed str16_test.txt
     12 var str16test string
     13 
     14 //go:embed str32_test.txt
     15 var str32test string
     16 
     17 type testCase struct {
     18 	decoded interface{}
     19 	encoded []byte
     20 }
     21 
     22 func makeStringCase(s string, prefix []byte) testCase {
     23 	return testCase{
     24 		decoded: s,
     25 		encoded: append(prefix, s...),
     26 	}
     27 }
     28 
     29 func makeBinaryCase(s []byte, prefix []byte) testCase {
     30 	return testCase{
     31 		decoded: s,
     32 		encoded: append(prefix, s...),
     33 	}
     34 }
     35 
     36 func makeMapCase(n int, prefix []byte) testCase {
     37 	var buf = prefix
     38 	for i := 0; i < n; i++ {
     39 		buf = append(
     40 			buf,
     41 			0xcf,
     42 			byte(i>>56), byte(i>>48), byte(i>>40), byte(i>>32),
     43 			byte(i>>24), byte(i>>16), byte(i>>8), byte(i),
     44 			1,
     45 		)
     46 	}
     47 	return testCase{newTestMap(n), buf}
     48 }
     49 
     50 var testCases = []testCase{
     51 	// bool
     52 	{true, []byte{0xc2}},
     53 	{false, []byte{0xc3}},
     54 
     55 	// fixint
     56 	{int(0), []byte{0}},
     57 	{int(2), []byte{2}},
     58 	{int(-1), []byte{0xff}},
     59 	{int(-32), []byte{0xe0}},
     60 
     61 	// positive int
     62 	{int(255), []byte{0xcc, 0xff}},
     63 	{int(256), []byte{0xcd, 0x01, 0x00}},
     64 	{int(65536), []byte{0xce, 0x00, 0x01, 0x00, 0x00}},
     65 	{int(4294967296), []byte{0xcf, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x00}},
     66 
     67 	// negative int
     68 	{int(-128), []byte{0xd0, 0x80}},
     69 	{int(-129), []byte{0xd1, 0xff, 0x7f}},
     70 	{int(-256), []byte{0xd1, 0xff, 0x00}},
     71 	{int(-32769), []byte{0xd2, 0xff, 0xff, 0x7f, 0xff}},
     72 	{int(-2147483649), []byte{0xd3, 0xff, 0xff, 0xff, 0xff, 0x7f, 0xff, 0xff, 0xff}},
     73 
     74 	// sized int
     75 	{int8(127), []byte{0xd0, 0x7f}},
     76 	{int8(-128), []byte{0xd0, 0x80}},
     77 	{int16(32767), []byte{0xd1, 0x7f, 0xff}},
     78 	{int16(-32768), []byte{0xd1, 0x80, 0x00}},
     79 	{int32(2147483647), []byte{0xd2, 0x7f, 0xff, 0xff, 0xff}},
     80 	{int32(-2147483648), []byte{0xd2, 0x80, 0x00, 0x00, 0x00}},
     81 	{int64(2147483648), []byte{0xd3, 0x00, 0x00, 0x00, 0x00, 0x80, 0x00, 0x00, 0x00}},
     82 	{int64(-2147483649), []byte{0xd3, 0xff, 0xff, 0xff, 0xff, 0x7f, 0xff, 0xff, 0xff}},
     83 	{int8(1), []byte{0xd0, 0x01}},
     84 	{int16(1), []byte{0xd1, 0x00, 0x01}},
     85 	{int32(1), []byte{0xd2, 0x00, 0x00, 0x00, 0x01}},
     86 	{int64(1), []byte{0xd3, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01}},
     87 
     88 	// fixint (uint)
     89 	{uint(0), []byte{0}},
     90 	{uint(2), []byte{2}},
     91 
     92 	// uint
     93 	{uint(255), []byte{0xcc, 0xff}},
     94 	{uint(256), []byte{0xcd, 0x01, 0x00}},
     95 	{uint(65536), []byte{0xce, 0x00, 0x01, 0x00, 0x00}},
     96 	{uint(4294967296), []byte{0xcf, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x00}},
     97 
     98 	// sized uint
     99 	{uint8(255), []byte{0xcc, 0xff}},
    100 	{uint16(256), []byte{0xcd, 0x01, 0x00}},
    101 	{uint32(65536), []byte{0xce, 0x00, 0x01, 0x00, 0x00}},
    102 	{uint64(4294967296), []byte{0xcf, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x00}},
    103 	{uint8(1), []byte{0xcc, 0x01}},
    104 	{uint16(1), []byte{0xcd, 0x00, 0x01}},
    105 	{uint32(1), []byte{0xce, 0x00, 0x00, 0x00, 0x01}},
    106 	{uint64(1), []byte{0xcf, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01}},
    107 
    108 	// float
    109 	{float32(3.141592), []byte{0xca, 0x40, 0x49, 0x0f, 0xd8}},
    110 	{float64(3.141592), []byte{0xcb, 0x40, 0x09, 0x21, 0xfa, 0xfc, 0x8b, 0x00, 0x7a}},
    111 
    112 	// String
    113 	makeStringCase("", []byte{0xa0}),
    114 	makeStringCase("Hello, World!", []byte{0xad}),
    115 	makeStringCase("Lorem ipsum dolor sit amet, consectetur porttitor.", []byte{0xd9, 0x32}),
    116 	makeStringCase(str16test, []byte{0xda, 0x77, 0xc7}),
    117 	makeStringCase(str32test, []byte{0xdb, 0x00, 0x01, 0x35, 0x05}),
    118 
    119 	// Binary
    120 	makeBinaryCase([]byte{}, []byte{0xc4, 0x00}),
    121 	makeBinaryCase([]byte("Hello, World!"), []byte{0xc4, 0x0d}),
    122 	makeBinaryCase([]byte("Lorem ipsum dolor sit amet, consectetur porttitor."), []byte{0xc4, 0x32}),
    123 	makeBinaryCase([]byte(str16test), []byte{0xc5, 0x77, 0xc7}),
    124 	makeBinaryCase([]byte(str32test), []byte{0xc6, 0x00, 0x01, 0x35, 0x05}),
    125 
    126 	// Array
    127 	{newTestArray(0), []byte{0x90}},
    128 	{newTestArray(1), []byte{0x91, 0x01}},
    129 	{newTestArray(2), []byte{0x92, 0x01, 0x01}},
    130 	{newTestArray(16), append([]byte{0xdc, 0x00, 0x10}, bytes.Repeat([]byte{0x01}, 16)...)},
    131 	{newTestArray(65536), append([]byte{0xdd, 0x00, 0x01, 0x00, 0x00}, bytes.Repeat([]byte{0x01}, 65536)...)},
    132 
    133 	// Map
    134 	makeMapCase(0, []byte{0x80}),
    135 	makeMapCase(1, []byte{0x81}),
    136 	makeMapCase(2, []byte{0x82}),
    137 	makeMapCase(16, []byte{0xde, 0x00, 0x10}),
    138 	makeMapCase(65536, []byte{0xdf, 0x00, 0x01, 0x00, 0x00}),
    139 
    140 	// Extension
    141 	{&testExt{1}, []byte{0xd4, 0x01, '_'}},
    142 	{&testExt{2}, []byte{0xd5, 0x01, '_', '_'}},
    143 	{&testExt{4}, append([]byte{0xd6, 0x01}, bytes.Repeat([]byte{'_'}, 4)...)},
    144 	{&testExt{8}, append([]byte{0xd7, 0x01}, bytes.Repeat([]byte{'_'}, 8)...)},
    145 	{&testExt{16}, append([]byte{0xd8, 0x01}, bytes.Repeat([]byte{'_'}, 16)...)},
    146 	{&testExt{3}, append([]byte{0xc7, 0x03, 0x01}, bytes.Repeat([]byte{'_'}, 3)...)},
    147 	{&testExt{256}, append([]byte{0xc8, 0x01, 0x00, 0x01}, bytes.Repeat([]byte{'_'}, 256)...)},
    148 	{&testExt{65536}, append([]byte{0xc9, 0x00, 0x01, 0x00, 0x00, 0x01}, bytes.Repeat([]byte{'_'}, 65536)...)},
    149 
    150 	// Timestamp
    151 	{
    152 		time.Date(1999, 3, 1, 0, 0, 0, 0, time.UTC), // 920246400
    153 		[]byte{0xd6, 0xff, 0x36, 0xd9, 0xd8, 0x80},
    154 	},
    155 	{
    156 		time.Date(2106, 2, 7, 6, 28, 16, 0, time.UTC), // 4294967296
    157 		[]byte{0xd7, 0xff, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x00},
    158 	},
    159 	{
    160 		time.Date(2021, 8, 12, 05, 57, 21, 536870912, time.UTC), // 1628747841.536870912
    161 		[]byte{0xd7, 0xff, 0x80, 0x00, 0x00, 0x00, 0x61, 0x14, 0xB8, 0x41},
    162 	},
    163 	{
    164 		time.Date(2514, 5, 30, 1, 53, 04, 536870912, time.UTC), // 17179869184.536870912
    165 		[]byte{0xc7, 0x0c, 0xff, 0x20, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x04, 0x00, 0x00, 0x00, 0x00},
    166 	},
    167 }
    168 
    169 type testArray []int
    170 
    171 var _ Array = (*testArray)(nil)
    172 
    173 func newTestArray(n int) *testArray {
    174 	arr := make(testArray, n)
    175 	for i := range arr {
    176 		arr[i] = 1
    177 	}
    178 	return &arr
    179 }
    180 
    181 func (t *testArray) EncodeMsgpackArray(e *Encoder) {
    182 	for i := 0; i < len(*t); i++ {
    183 		e.Int(1)
    184 	}
    185 }
    186 
    187 func (t *testArray) DecodeMsgpackArray(d *Decoder, n int) error {
    188 	*t = make(testArray, n)
    189 	var v int
    190 	for i := 0; i < n; i++ {
    191 		err := d.Int(&v)
    192 		if err != nil {
    193 			return err
    194 		}
    195 		(*t)[i] = v
    196 	}
    197 	return nil
    198 }
    199 
    200 func (t *testArray) Len() int {
    201 	return len(*t)
    202 }
    203 
    204 type testMap []int
    205 
    206 var _ Map = (*testMap)(nil)
    207 
    208 func newTestMap(n int) *testMap {
    209 	v := make(testMap, n)
    210 	for i := 0; i < n; i++ {
    211 		v[i] = 1
    212 	}
    213 	return &v
    214 }
    215 
    216 func (t *testMap) EncodeMsgpackMap(e *Encoder) {
    217 	for k, v := range *t {
    218 		e.Uint64(uint64(k))
    219 		e.Int(v)
    220 	}
    221 }
    222 
    223 func (t *testMap) DecodeMsgpackMap(d *Decoder, n int) error {
    224 	*t = make(testMap, n)
    225 
    226 	var (
    227 		key uint64
    228 		val int
    229 		err error
    230 	)
    231 
    232 	for i := 0; i < n; i++ {
    233 		err = d.Uint64(&key)
    234 		if err != nil {
    235 			return err
    236 		}
    237 
    238 		err = d.Int(&val)
    239 		if err != nil {
    240 			return err
    241 		}
    242 
    243 		(*t)[key] = val
    244 	}
    245 
    246 	return nil
    247 }
    248 
    249 func (t *testMap) Size() int {
    250 	return len(*t)
    251 }
    252 
    253 type testExt struct {
    254 	n int
    255 }
    256 
    257 var _ Extension = (*testExt)(nil)
    258 
    259 func (t *testExt) EncodeMsgpackExt(e *Encoder) {
    260 	e.Raw(bytes.Repeat([]byte{'_'}, t.n))
    261 }
    262 
    263 func (t *testExt) DecodeMsgpackExt(d *Decoder, typ int8, size int) error {
    264 	if typ != t.Type() {
    265 		return fmt.Errorf("ext/decode: expected type was %d, got: %d", t.Type(), typ)
    266 	}
    267 	t.n = size
    268 
    269 	buf := make([]byte, t.n)
    270 	err := d.Raw(buf)
    271 	if err != nil {
    272 		return err
    273 	}
    274 	if !bytes.Equal(buf, bytes.Repeat([]byte{'_'}, t.n)) {
    275 		return fmt.Errorf("ext/decode: expected value was []byte{'_' * %d}, got: %v", t.n, buf)
    276 	}
    277 	return nil
    278 }
    279 
    280 func (t *testExt) Type() int8 {
    281 	return 1
    282 }
    283 
    284 func (t *testExt) Size() int {
    285 	return t.n
    286 }