1package msgp
2
3// size of every object on the wire,
4// plus type information. gives us
5// constant-time type information
6// for traversing composite objects.
7//
8var sizes = [256]bytespec{
9	mnil:      {size: 1, extra: constsize, typ: NilType},
10	mfalse:    {size: 1, extra: constsize, typ: BoolType},
11	mtrue:     {size: 1, extra: constsize, typ: BoolType},
12	mbin8:     {size: 2, extra: extra8, typ: BinType},
13	mbin16:    {size: 3, extra: extra16, typ: BinType},
14	mbin32:    {size: 5, extra: extra32, typ: BinType},
15	mext8:     {size: 3, extra: extra8, typ: ExtensionType},
16	mext16:    {size: 4, extra: extra16, typ: ExtensionType},
17	mext32:    {size: 6, extra: extra32, typ: ExtensionType},
18	mfloat32:  {size: 5, extra: constsize, typ: Float32Type},
19	mfloat64:  {size: 9, extra: constsize, typ: Float64Type},
20	muint8:    {size: 2, extra: constsize, typ: UintType},
21	muint16:   {size: 3, extra: constsize, typ: UintType},
22	muint32:   {size: 5, extra: constsize, typ: UintType},
23	muint64:   {size: 9, extra: constsize, typ: UintType},
24	mint8:     {size: 2, extra: constsize, typ: IntType},
25	mint16:    {size: 3, extra: constsize, typ: IntType},
26	mint32:    {size: 5, extra: constsize, typ: IntType},
27	mint64:    {size: 9, extra: constsize, typ: IntType},
28	mfixext1:  {size: 3, extra: constsize, typ: ExtensionType},
29	mfixext2:  {size: 4, extra: constsize, typ: ExtensionType},
30	mfixext4:  {size: 6, extra: constsize, typ: ExtensionType},
31	mfixext8:  {size: 10, extra: constsize, typ: ExtensionType},
32	mfixext16: {size: 18, extra: constsize, typ: ExtensionType},
33	mstr8:     {size: 2, extra: extra8, typ: StrType},
34	mstr16:    {size: 3, extra: extra16, typ: StrType},
35	mstr32:    {size: 5, extra: extra32, typ: StrType},
36	marray16:  {size: 3, extra: array16v, typ: ArrayType},
37	marray32:  {size: 5, extra: array32v, typ: ArrayType},
38	mmap16:    {size: 3, extra: map16v, typ: MapType},
39	mmap32:    {size: 5, extra: map32v, typ: MapType},
40}
41
42func init() {
43	// set up fixed fields
44
45	// fixint
46	for i := mfixint; i < 0x80; i++ {
47		sizes[i] = bytespec{size: 1, extra: constsize, typ: IntType}
48	}
49
50	// nfixint
51	for i := uint16(mnfixint); i < 0x100; i++ {
52		sizes[uint8(i)] = bytespec{size: 1, extra: constsize, typ: IntType}
53	}
54
55	// fixstr gets constsize,
56	// since the prefix yields the size
57	for i := mfixstr; i < 0xc0; i++ {
58		sizes[i] = bytespec{size: 1 + rfixstr(i), extra: constsize, typ: StrType}
59	}
60
61	// fixmap
62	for i := mfixmap; i < 0x90; i++ {
63		sizes[i] = bytespec{size: 1, extra: varmode(2 * rfixmap(i)), typ: MapType}
64	}
65
66	// fixarray
67	for i := mfixarray; i < 0xa0; i++ {
68		sizes[i] = bytespec{size: 1, extra: varmode(rfixarray(i)), typ: ArrayType}
69	}
70}
71
72// a valid bytespsec has
73// non-zero 'size' and
74// non-zero 'typ'
75type bytespec struct {
76	size  uint8   // prefix size information
77	extra varmode // extra size information
78	typ   Type    // type
79	_     byte    // makes bytespec 4 bytes (yes, this matters)
80}
81
82// size mode
83// if positive, # elements for composites
84type varmode int8
85
86const (
87	constsize varmode = 0  // constant size (size bytes + uint8(varmode) objects)
88	extra8            = -1 // has uint8(p[1]) extra bytes
89	extra16           = -2 // has be16(p[1:]) extra bytes
90	extra32           = -3 // has be32(p[1:]) extra bytes
91	map16v            = -4 // use map16
92	map32v            = -5 // use map32
93	array16v          = -6 // use array16
94	array32v          = -7 // use array32
95)
96
97func getType(v byte) Type {
98	return sizes[v].typ
99}
100