1 # This file is part of NIT ( http://www.nitlanguage.org ).
3 # Licensed under the Apache License, Version 2.0 (the "License");
4 # you may not use this file except in compliance with the License.
5 # You may obtain a copy of the License at
7 # http://www.apache.org/licenses/LICENSE-2.0
9 # Unless required by applicable law or agreed to in writing, software
10 # distributed under the License is distributed on an "AS IS" BASIS,
11 # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
12 # See the License for the specific language governing permissions and
13 # limitations under the License.
15 # Low-level write in MessagePack format to `Writer` streams
22 # Write `null`, or nil, in MessagePack format
23 fun write_msgpack_null
do write_byte
0xC0u
8
25 # Write `bool` in MessagePack format
26 fun write_msgpack_bool
(bool
: Bool)
27 do write_byte
(if bool
then 0xC3u
8 else 0xC2u
8)
32 # Write the integer `value` either as the shortest possible MessagePack _int_
33 fun write_msgpack_int
(value
: Int)
35 if value
>= -0x20 and value
<= 0x7F then
36 write_msgpack_fixint value
37 else if value
>= 0 then
39 write_msgpack_uint8 value
40 else if value
<= 0xFFFF then
41 write_msgpack_uint16 value
42 else if value
<= 0xFFFF_FFFF
then
43 write_msgpack_uint32 value
44 else #if value <= 0xFFFF_FFFF_FFFF_FFFF then
45 write_msgpack_uint64 value
47 else if value
>= -128 then
48 write_msgpack_int8 value
49 else if value
>= -32768 then
50 write_msgpack_int16 value
51 else if value
>= -2147483648 then
52 write_msgpack_int32 value
54 write_msgpack_int64 value
58 # Write `value` as a single byte with metadata
60 # Require: `value >= -0x20 and value <= 0x7F`
61 fun write_msgpack_fixint
(value
: Int)
63 assert value
>= -0x20 and value
<= 0x7F
67 # Write `value` over one unsigned byte, following 1 metadata byte
69 # Require: `value >= 0x00 and value <= 0xFF`
70 fun write_msgpack_uint8
(value
: Int)
73 write_bytes value
.to_bytes
(n_bytes
=1)
76 # Write `value` over two unsigned bytes, following 1 metadata byte
78 # Require: `value >= 0x00 and value <= 0xFFFF`
79 fun write_msgpack_uint16
(value
: Int)
82 write_bytes value
.to_bytes
(n_bytes
=2)
85 # Write `value` over 4 unsigned bytes, following 1 metadata byte
87 # Require: `value >= 0x00 and value <= 0xFFFF_FFFF`
88 fun write_msgpack_uint32
(value
: Int)
91 write_bytes value
.to_bytes
(n_bytes
=4)
94 # Write `value` over 8 unsigned bytes, following 1 metadata byte
96 # Require: `value >= 0x00 and value <= 0xFFFF_FFFF_FFFF_FFFF`
97 fun write_msgpack_uint64
(value
: Int)
100 write_bytes value
.to_bytes
(n_bytes
=8)
103 # Write `value` over one signed byte, following 1 metadata byte
105 # Require: `value >= -128 and value <= 127`
106 fun write_msgpack_int8
(value
: Int)
109 write_bytes value
.to_bytes
(n_bytes
=1)
112 # Write `value` over two signed bytes, following 1 metadata byte
113 fun write_msgpack_int16
(value
: Int)
116 write_bytes value
.to_bytes
(n_bytes
=2)
119 # Write `value` over 4 signed bytes, following 1 metadata byte
120 fun write_msgpack_int32
(value
: Int)
123 write_bytes value
.to_bytes
(n_bytes
=4)
126 # Write `value` over 8 signed bytes, following 1 metadata byte
127 fun write_msgpack_int64
(value
: Int)
136 # Write `value` as a MessagePack float (losing precision)
137 fun write_msgpack_float
(value
: Float)
143 # Write `value` as a MessagePack double
144 fun write_msgpack_double
(value
: Float)
153 # Write `text` in the shortest possible MessagePack format
155 # Require: `text.byte_length <= 0xFFFF_FFFF`
156 fun write_msgpack_str
(text
: Text)
158 var len
= text
.byte_length
160 write_msgpack_fixstr text
161 else if len
<= 0xFF then
162 write_msgpack_str8 text
163 else if len
<= 0xFFFF then
164 write_msgpack_str16 text
165 else if len
<= 0xFFFF_FFFF
then
166 write_msgpack_str32 text
172 # Write `text` in _fixstr_ format, max of 0x1F bytes
174 # Require: `text.byte_length <= 0x1F`
175 fun write_msgpack_fixstr
(text
: Text)
177 var len
= text
.byte_length
180 var b
= 0b1010_0000u
8 | len
.to_b
186 # Write `text` in _str8_ format, max of 0xFF bytes
188 # Require: `text.byte_length <= 0xFF`
189 fun write_msgpack_str8
(text
: Text)
191 var len
= text
.byte_length
199 # Write `text` in _str16_ format, max of 0xFFFF bytes
201 # Require: `text.byte_length <= 0xFFFF`
202 fun write_msgpack_str16
(text
: Text)
204 var len
= text
.byte_length
208 var len_bytes
= len
.to_bytes
209 write_byte len_bytes
[0]
210 write_byte
if len_bytes
.length
> 1 then len_bytes
[1] else 0u8
214 # Write `text` in _str32_ format, max of 0xFFFF_FFFF bytes
216 # Require: `text.byte_length <= 0xFFFF_FFFF`
217 fun write_msgpack_str32
(text
: Text)
219 var len
= text
.byte_length
220 assert len
<= 0xFFFF_FFFF
223 var len_bytes
= len
.to_bytes
224 write_byte len_bytes
[0]
226 write_byte
if len_bytes
.length
> i
then len_bytes
[i
] else 0u8
234 # Write `data` in the shortest possible MessagePack _bin_ format
236 # Require: `data.length <= 0xFFFF_FFFF`
237 fun write_msgpack_bin
(data
: Bytes)
239 var len
= data
.length
241 write_msgpack_bin8 data
242 else if len
<= 0xFFFF then
243 write_msgpack_bin16 data
244 else if len
<= 0xFFFF_FFFF
then
245 write_msgpack_bin32 data
249 # Write `data` in _bin8_ format, max of 0xFF bytes
251 # Require: `data.length <= 0xFF`
252 fun write_msgpack_bin8
(data
: Bytes)
254 var len
= data
.length
262 # Write `data` in _bin16_ format, max of 0xFFFF bytes
264 # Require: `data.length <= 0xFFFF`
265 fun write_msgpack_bin16
(data
: Bytes)
267 var len
= data
.length
271 write_bytes len
.to_bytes
(n_bytes
=2)
275 # Write `data` in _bin32_ format, max of 0xFFFF_FFFF bytes
277 # Require: `data.length <= 0xFFFF_FFFF`
278 fun write_msgpack_bin32
(data
: Bytes)
280 var len
= data
.length
281 assert len
<= 0xFFFF_FFFF
284 write_bytes len
.to_bytes
(n_bytes
=4)
291 # Write an array header for `len` items in the shortest possible MessagePack _array_ format
293 # After writing the header, clients should write the array items.
295 # Require: `len <= 0xFFFF_FFFF`
296 fun write_msgpack_array
(len
: Int)
299 write_msgpack_fixarray len
300 else if len
<= 0xFFFF then
301 write_msgpack_array16 len
302 else if len
<= 0xFFFF_FFFF
then
303 write_msgpack_array32 len
309 # Write an array header for `len` items, max of 0x0F items
311 # After writing the header, clients should write the array items.
313 # Require: `len <= 0x0F`
314 fun write_msgpack_fixarray
(len
: Int)
317 write_byte
0b1001_0000u
8 | len
.to_b
320 # Write an array header for `len` items, max of 0xFFFF items
322 # After writing the header, clients should write the array items.
324 # Require: `len <= 0xFFFF`
325 fun write_msgpack_array16
(len
: Int)
329 write_bytes len
.to_bytes
(n_bytes
=2)
332 # Write an array header for `len` items, max of 0xFFFF_FFFF items
334 # After writing the header, clients should write the array items.
336 # Require: `len <= 0xFFFF_FFFF`
337 fun write_msgpack_array32
(len
: Int)
339 assert len
<= 0xFFFF_FFFF
341 write_bytes len
.to_bytes
(n_bytes
=4)
347 # Write a map header for `len` keys/value pairs in the shortest possible MessagePack _map_ format
349 # After writing the header, clients should write the map data, alternating
350 # between keys and values.
352 # Require: `len <= 0xFFFF_FFFF`
353 fun write_msgpack_map
(len
: Int)
356 write_msgpack_fixmap len
357 else if len
<= 0xFFFF then
358 write_msgpack_map16 len
359 else if len
<= 0xFFFF_FFFF
then
360 write_msgpack_map32 len
366 # Write a map header for `len` key/value pairs, max of 0x0F pairs
368 # After writing the header, clients should write the map data, alternating
369 # between keys and values.
371 # Require: `len <= 0x0F`
372 fun write_msgpack_fixmap
(len
: Int)
375 write_byte
0b1000_0000u
8 | len
.to_b
378 # Write a map header for `len` key/value pairs, max of 0xFFFF pairs
380 # After writing the header, clients should write the map data, alternating
381 # between keys and values.
383 # Require: `len <= 0xFFFF`
384 fun write_msgpack_map16
(len
: Int)
388 write_bytes len
.to_bytes
(n_bytes
=2)
391 # Write a map header for `len` key/value pairs, max of 0xFFFF_FFFF pairs
393 # After writing the header, clients should write the map data, alternating
394 # between keys and values.
396 # Require: `len <= 0xFFFF_FFFF`
397 fun write_msgpack_map32
(len
: Int)
399 assert len
<= 0xFFFF_FFFF
401 write_bytes len
.to_bytes
(n_bytes
=4)
407 # Write an application-specific extension for `typ` and `bytes` in the shortest possible MessagePack _ext_ format
409 # Require: `bytes.length <= 0xFFFF_FFFF`
412 # var writer = new BytesWriter
413 # writer.write_msgpack_ext(0x0Au8, b"\x0B\x0C\x0D")
414 # assert writer.bytes == b"\xC7\x03\x0A\x0B\x0C\x0D"
416 fun write_msgpack_ext
(typ
: Byte, bytes
: Bytes)
418 var len
= bytes
.length
420 write_msgpack_fixext1 typ
421 write_byte bytes
.first
422 else if len
== 2 then
423 write_msgpack_fixext2 typ
425 else if len
== 4 then
426 write_msgpack_fixext4 typ
428 else if len
== 8 then
429 write_msgpack_fixext8 typ
431 else if len
== 16 then
432 write_msgpack_fixext16 typ
434 else if len
<= 0xFF then
435 write_msgpack_ext8
(typ
, len
)
437 else if len
<= 0xFFFF then
438 write_msgpack_ext16
(typ
, len
)
440 else if len
<= 0xFFFF_FFFF
then
441 write_msgpack_ext32
(typ
, len
)
448 # Write the header for an application-specific extension of one data byte
450 # After writing the header, clients should write the data byte.
451 fun write_msgpack_fixext1
(typ
: Byte)
457 # Write the header for an application-specific extension of two data bytes
459 # After writing the header, clients should write the two data bytes.
460 fun write_msgpack_fixext2
(typ
: Byte)
466 # Write the header for an application-specific extension of 4 data bytes
468 # After writing the header, clients should write the 4 data bytes.
469 fun write_msgpack_fixext4
(typ
: Byte)
475 # Write the header for an application-specific extension of 8 data bytes
477 # After writing the header, clients should write the 8 data bytes.
478 fun write_msgpack_fixext8
(typ
: Byte)
484 # Write the header for an application-specific extension of 16 data bytes
486 # After writing the header, clients should write the 16 data bytes.
487 fun write_msgpack_fixext16
(typ
: Byte)
493 # Write the header for an application-specific extension of `len` data bytes
495 # After writing the header, clients should write the data bytes.
497 # Require: `len >= 0 and <= 0xFF`
498 fun write_msgpack_ext8
(typ
: Byte, len
: Int)
500 assert len
>= 0 and len
<= 0xFF
506 # Write the header for an application-specific extension of `len` data bytes
508 # After writing the header, clients should write the data bytes.
510 # Require: `len >= 0 and <= 0xFFFF`
511 fun write_msgpack_ext16
(typ
: Byte, len
: Int)
513 assert len
>= 0 and len
<= 0xFFFF
515 write_bytes len
.to_bytes
(n_bytes
=2)
519 # Write the header for an application-specific extension of `len` data bytes
521 # After writing the header, clients should write the data bytes.
523 # Require: `len >= 0 and <= 0xFFFF_FFFF`
524 fun write_msgpack_ext32
(typ
: Byte, len
: Int)
526 assert len
>= 0 and len
<= 0xFFFF_FFFF
528 write_bytes len
.to_bytes
(n_bytes
=4)