3b8854aca14a30195a2d592ab8d9eedc5be5a3d7
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 read MessagePack format from `Reader` streams
25 # Read the next MessagePack object and return it as a simple Nit object
27 # The return value is composed of:
28 # * the simple types `null`, `Bool`, `Int`, `Float`, `String` and `Bytes`,
29 # * collections of simple Nit objects `Array[nullable Serializable]`
30 # and `Map[nullable Serializable, nullable Serializable]`,
31 # * and `MsgPackExt` for custom MessagePack *ext* data.
33 # This method reads plain MessagePack data, as written by `MsgPackSerializer`
34 # when `plain_msgpack == true`. To deserialize full Nit objects from
35 # MessagePack with metadata use `Reader::deserialize_msgpack`.
36 fun read_msgpack
: nullable Serializable
38 if last_error
!= null then return 0
42 # Error, return default `null`
45 else if typ
& 0b1000_0000 == 0 or typ
& 0b1110_0000 == 0b1110_0000 then
47 var bytes
= new Bytes.with_capacity
(1)
49 return bytes
.to_i
(signed
=true)
51 else if typ
& 0b1111_0000 == 0b1000_0000 then
53 var len
= typ
& 0b0000_1111
54 return read_msgpack_map_data
(len
.to_i
)
56 else if typ
& 0b1111_0000 == 0b1001_0000 then
58 var len
= typ
& 0b0000_1111
59 return read_msgpack_array_data
(len
.to_i
)
61 else if typ
& 0b1110_0000 == 0b1010_0000 then
63 var len
= typ
& 0b0001_1111
64 return read_bytes
(len
.to_i
).to_s
66 else if typ
== 0xC0 then
68 else if typ
== 0xC2 then
70 else if typ
== 0xC3 then
73 else if typ
>= 0xCC and typ
<= 0xCF then
74 # uint8, 16, 32 and 64
75 var len
= 1 << (typ
- 0xCC)
76 return read_bytes
(len
).to_i
78 else if typ
>= 0xD0 and typ
<= 0xD3 then
80 var len
= 1 << (typ
- 0xD0)
81 return read_bytes
(len
).to_i
(true)
83 else if typ
== 0xCA then
85 else if typ
== 0xCB then
88 else if typ
>= 0xD9 and typ
<= 0xDB then
90 var len_ln
= 1 << (typ
- 0xD9)
91 var bf
= read_bytes
(len_ln
)
93 if len
< 0 then return null
94 var rd_buf
= read_bytes
(len
)
95 if rd_buf
.length
!= len
then
96 # Bad formatted message.
101 else if typ
>= 0xC4 and typ
<= 0xC6 then
103 var len_ln
= 1 << (typ
- 0xC4)
104 var bf
= read_bytes
(len_ln
)
106 if len
< 0 then return null
107 var rd_buf
= read_bytes
(len
)
108 if rd_buf
.length
!= len
then
109 # Bad formatted message.
114 else if typ
== 0xDC or typ
== 0xDD then
115 # array16 and array32
116 var len_ln
= 2 << (typ
- 0xDC)
117 var lenbuf
= read_bytes
(len_ln
)
118 return read_msgpack_array_data
(lenbuf
.to_i
)
120 else if typ
== 0xDE or typ
== 0xDF then
122 var len_ln
= 2 << (typ
- 0xDE)
123 var lenbuf
= read_bytes
(len_ln
)
124 return read_msgpack_map_data
(lenbuf
.to_i
)
126 else if typ
== 0xD4 then
128 return read_msgpack_fixext_data
(1)
129 else if typ
== 0xD5 then
131 return read_msgpack_fixext_data
(2)
132 else if typ
== 0xD6 then
134 return read_msgpack_fixext_data
(4)
135 else if typ
== 0xD7 then
137 return read_msgpack_fixext_data
(8)
138 else if typ
== 0xD8 then
140 return read_msgpack_fixext_data
(16)
142 else if typ
== 0xC7 then
144 return read_msgpack_ext_data
(1)
145 else if typ
== 0xC8 then
147 return read_msgpack_ext_data
(2)
148 else if typ
== 0xC9 then
150 return read_msgpack_ext_data
(4)
153 print_error
"MessagePack Warning: Found no match for typ {typ.to_base(16)} / 0b{typ.to_base(2)}"
157 # Read the content of a map, `len` keys and values
158 private fun read_msgpack_map_data
(len
: Int): Map[nullable Serializable, nullable Serializable]
160 var map
= new Map[nullable Serializable, nullable Serializable]
161 for i
in [0..len
.to_i
[ do map
[read_msgpack
] = read_msgpack
165 # Read the content of an array of `len` items
166 private fun read_msgpack_array_data
(len
: Int): Array[nullable Serializable]
168 return [for i
in [0..len
[ do read_msgpack
]
171 # Read the content of a *fixext* of `len` bytes
174 # var reader = new BytesReader(b"\xC7\x03\x0A\x0B\x0C\x0D")
175 # var ext = reader.read_msgpack
176 # assert ext isa MsgPackExt
177 # assert ext.typ == 0x0Au8
178 # assert ext.data == b"\x0B\x0C\x0D"
180 private fun read_msgpack_fixext_data
(len
: Int): MsgPackExt
182 var exttyp
= read_byte
183 if exttyp
< 0 then exttyp
= 0
184 var data
= read_bytes
(len
)
185 return new MsgPackExt(exttyp
.to_b
, data
)
188 # Read the content of a dynamic *ext* including the length on `len_len` bytes
189 private fun read_msgpack_ext_data
(len_len
: Int): MsgPackExt
191 var len
= read_bytes
(len_len
).to_i
192 return read_msgpack_fixext_data
(len
)