-
-
Notifications
You must be signed in to change notification settings - Fork 0
Expand file tree
/
Copy pathmsgpack.wren
More file actions
198 lines (192 loc) · 6.83 KB
/
msgpack.wren
File metadata and controls
198 lines (192 loc) · 6.83 KB
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
// MessagePack serializer and deserializer implementation.
//
// [MessagePack](https://msgpack.org) is a binary serialization specification.
// See: https://msgpack.org
class MsgPack {
// Serializes given `data`.
// Returns: String buffer of bytes containing the serialized data.
// See: https://github.com/msgpack/msgpack/blob/master/spec.md#serialization-type-to-format-conversion
static pack(data) {
}
// Deserializes given `buffer`.
// Params: buffer: String buffer of bytes to deserialize.
// Returns: List|Map containing deserialized data.
// Throws: When malformed data is encountered or deserialization does not otherwise succeed.
// See: https://github.com/msgpack/msgpack/blob/master/spec.md#deserialization-format-to-type-conversion
static unpack(buffer) {}
}
// A MessagePack serializer.
// See: https://github.com/msgpack/msgpack/blob/master/spec.md#formats
class Packer {
static pack(value) {
if (value is Num) {
if (value.isInteger) {
// Positive fixInt
if (value >= 0 && value <= 0x7F) return value & 0x7F
// Negative fixInt
if (value < 0 && ~value <= 0x1F) return 0xE0 | (value & 0x1F)
// Unsigned 8-bit integer
if (value >= 0 && (value & 0x100) <= 0xFF) return [Tokens.uint8, Packer.bytes(value)]
// Unsigned 16-bit integer
if (value >= 0 && (value & 0x10000) <= 0xFFFF) return [Tokens.uint16, Packer.bytes(value)]
// Unsigned 32-bit integer
if (value >= 0) return [Tokens.uint32, Packer.bytes(value)]
// Signed 8-bit integer
if (~value <= 0xFF) return [Tokens.int8, Packer.bytes(value)]
// Signed 16-bit integer
if (~value <= 0xFFFF) return [Tokens.int16, Packer.bytes(value)]
// Signed 32-bit integer
return [Tokens.int32, Packer.bytes(value)]
}
// Signed 64-bit float
return [Tokens.float64, Packer.bytes(value)]
}
if (value is String) {
value = value.bytes
// +--------+========+
// |101XXXXX| data |
// +--------+========+
// Where XXXXX is a 5-bit unsigned integer which represents value.count
if (value.count < 32) return [0xA0 | (value.count & 0x1F), value]
// +--------+--------+========+
// | 0xd9 |YYYYYYYY| data |
// +--------+--------+========+
if (value.count < (2.pow(8))-1) return [Tokens.str8, value.count & 0xFF, value]
// +--------+--------+--------+========+
// | 0xda |ZZZZZZZZ|ZZZZZZZZ| data |
// +--------+--------+--------+========+
if (value.count < (2.pow(16))-1) return [Tokens.str16, value.count & 0xFFFF, value]
// +--------+--------+--------+--------+--------+========+
// | 0xdb |AAAAAAAA|AAAAAAAA|AAAAAAAA|AAAAAAAA| data |
// +--------+--------+--------+--------+--------+========+
if (value.count < (2.pow(32))-1) return [Tokens.str32, value.count & 0xFFFFFFFF, value]
}
if (value is List) {}
if (value is Map) {}
Fiber.abort("Unimplemented!")
}
static bytes(value) {
// 8-bit integers
if (value is Num && ((value < 0 ? ~value : value) & 0x100) < 0x100) return value & 0xFF
// 16-bit integers
if (value is Num && ((value < 0 ? ~value : value) & 0x10000) < 0x10000) return value & 0xFFFF
// NaN, ±infinity, and other 32-bit integers and floats
if (value is Num) return value & 0xFFFFFFFF
if (value is String) return value.bytes
Fiber.abort("Cannot get binary representation of '%(value)'")
}
}
import "wren-magpie/magpie" for Magpie, Result
// See: https://github.com/msgpack/msgpack/blob/master/spec.md
class Grammar {
// Section: Integers
// See: https://github.com/msgpack/msgpack/blob/master/spec.md#int-format-family
static fixInt {}
static uint8 {}
static uint16 {}
static uint32 {}
static uint64 {
Fiber.abort("Wren does not support 64-bit numbers.")
}
static int8 {}
static int16 {}
static int32 {}
static int64 {
Fiber.abort("Wren does not support 64-bit numbers.")
}
// Section: Floating-Point Numbers
// See: https://github.com/msgpack/msgpack/blob/master/spec.md#float-format-family
static float32 {}
static float64 {}
// Section: Strings
// See: https://github.com/msgpack/msgpack/blob/master/spec.md#str-format-family
static fixStr {}
static str8 {}
static str16 {}
static str32 {}
// Section: Binary
// See: https://github.com/msgpack/msgpack/blob/master/spec.md#bin-format-family
static bin8 {}
static bin16 {}
static bin32 {}
// Section: Arrays
// See: https://github.com/msgpack/msgpack/blob/master/spec.md#array-format-family
static fixArray {}
static array16 {}
static array32 {}
// Section: Maps
// See: https://github.com/msgpack/msgpack/blob/master/spec.md#map-format-family
static fixMap {}
static map16 {}
static map32 {}
// Section: Extensions
// See: https://github.com/msgpack/msgpack/blob/master/spec.md#ext-format-family
static fixExt {}
static fixExt2 {}
static fixExt4 {}
static fixExt8 {}
static fixExt16 {}
static ext8 {}
static ext16 {}
static ext32 {}
// Section: Timestamp
// See: https://github.com/msgpack/msgpack/blob/master/spec.md#timestamp-format-family
static timestamp32 {}
static timestamp64 {}
static timestamp96 {}
}
// See: https://github.com/msgpack/msgpack/blob/master/spec.md#formats
class Tokens {
static positiveFixInt { (0x00..0x7F) }
static fixMap { (0x80..0x8F) }
static fixArray { (0x90..0x9F) }
static fixStr { (0xA0..0xBF) }
static nil { 0xC0 }
static false_ { 0xC2 }
static true_ { 0xC3 }
static bin8 { 0xC4 }
static bin16 { 0xC5 }
static bin32 { 0xC6 }
static ext8 { 0xC7 }
static ext16 { 0xC8 }
static ext32 { 0xC9 }
// An IEEE 754 single-precision float is a 32-bit value with this layout:
//
// 1 Sign bit
// | 8 Exponent bits
// | | 24 Mantissa (i.e. fraction) bits
// | | |
// S[Exponent-][Mantissa----------------]
// See: https://github.com/msgpack/msgpack/blob/master/spec.md#float-format-family
static float32 { 0xCA }
// An IEEE 754 double-precision float is a 64-bit value with this layout:
//
// 1 Sign bit
// | 11 Exponent bits
// | | 52 Mantissa (i.e. fraction) bits
// | | |
// S[Exponent-][Mantissa------------------------------------------]
// See: https://github.com/msgpack/msgpack/blob/master/spec.md#float-format-family
static float64 { 0xCB }
static uint8 { 0xCC }
static uint16 { 0xCD }
static uint32 { 0xCE }
static uint64 { 0xCF }
static int8 { 0xD0 }
static int16 { 0xD1 }
static int32 { 0xD2 }
static int64 { 0xD3 }
static fixExt { 0xD4 }
static fixExt2 { 0xD5 }
static fixExt4 { 0xD6 }
static fixExt8 { 0xD7 }
static fixExt16 { 0xD8 }
static str8 { 0xD9 }
static str16 { 0xDA }
static str32 { 0xDB }
static array16 { 0xDC }
static array32 { 0xDD }
static map16 { 0xDE }
static map32 { 0xDF }
static negativeFixInt { (0xE0..0xFF) }
}