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_0000u
8 == 0u8
or typ
& 0b1110_0000u
8 == 0b1110_0000u
8 then
47 var bytes
= new Bytes.with_capacity
(1)
49 return bytes
.to_i
(signed
=true)
51 else if typ
& 0b1111_0000u
8 == 0b1000_0000u
8 then
53 var len
= typ
& 0b0000_1111u
8
54 return read_msgpack_map_data
(len
.to_i
)
56 else if typ
& 0b1111_0000u
8 == 0b1001_0000u
8 then
58 var len
= typ
& 0b0000_1111u
8
59 return read_msgpack_array_data
(len
.to_i
)
61 else if typ
& 0b1110_0000u
8 == 0b1010_0000u
8 then
63 var len
= typ
& 0b0001_1111u
8
64 return read_bytes
(len
.to_i
).to_s
66 else if typ
== 0xC0u
8 then
68 else if typ
== 0xC2u
8 then
70 else if typ
== 0xC3u
8 then
73 else if typ
== 0xCCu
8 then
75 return (read_byte
or else 0u8
).to_i
76 else if typ
== 0xCDu
8 then
78 return read_bytes
(2).to_i
79 else if typ
== 0xCEu
8 then
81 return read_bytes
(4).to_i
82 else if typ
== 0xCFu
8 then
84 return read_bytes
(8).to_i
85 else if typ
== 0xD0u
8 then
87 return read_bytes
(1).to_i
(true)
88 else if typ
== 0xD1u
8 then
90 return read_bytes
(2).to_i
(true)
91 else if typ
== 0xD2u
8 then
93 return read_bytes
(4).to_i
(true)
94 else if typ
== 0xD3u
8 then
98 else if typ
== 0xCAu
8 then
100 else if typ
== 0xCBu
8 then
103 else if typ
== 0xD9u
8 then
106 if len
== null then return null
107 return read_bytes
(len
.to_i
).to_s
108 else if typ
== 0xDAu
8 then
110 var len
= read_bytes
(2)
111 return read_bytes
(len
.to_i
).to_s
112 else if typ
== 0xDBu
8 then
114 var len
= read_bytes
(4)
115 return read_bytes
(len
.to_i
).to_s
117 else if typ
== 0xC4u
8 then
120 if len
== null then return null
121 return read_bytes
(len
.to_i
)
122 else if typ
== 0xC5u
8 then
124 var len
= read_bytes
(2)
125 return read_bytes
(len
.to_i
)
126 else if typ
== 0xC6u
8 then
128 var len
= read_bytes
(4)
129 return read_bytes
(len
.to_i
)
131 else if typ
== 0xDCu
8 then
133 var len
= read_bytes
(2)
134 return read_msgpack_array_data
(len
.to_i
)
135 else if typ
== 0xDDu
8 then
137 var len
= read_bytes
(4)
138 return read_msgpack_array_data
(len
.to_i
)
140 else if typ
== 0xDEu
8 then
142 var len
= read_bytes
(2)
143 return read_msgpack_map_data
(len
.to_i
)
144 else if typ
== 0xDFu
8 then
146 var len
= read_bytes
(4)
147 return read_msgpack_map_data
(len
.to_i
)
149 else if typ
== 0xD4u
8 then
151 return read_msgpack_fixext_data
(1)
152 else if typ
== 0xD5u
8 then
154 return read_msgpack_fixext_data
(2)
155 else if typ
== 0xD6u
8 then
157 return read_msgpack_fixext_data
(4)
158 else if typ
== 0xD7u
8 then
160 return read_msgpack_fixext_data
(8)
161 else if typ
== 0xD8u
8 then
163 return read_msgpack_fixext_data
(16)
165 else if typ
== 0xC7u
8 then
167 return read_msgpack_ext_data
(1)
168 else if typ
== 0xC8u
8 then
170 return read_msgpack_ext_data
(2)
171 else if typ
== 0xC9u
8 then
173 return read_msgpack_ext_data
(4)
176 print_error
"MessagePack Warning: Found no match for typ {typ} / 0b{typ.to_i.to_base(2)}"
180 # Read the content of a map, `len` keys and values
181 private fun read_msgpack_map_data
(len
: Int): Map[nullable Serializable, nullable Serializable]
183 var map
= new Map[nullable Serializable, nullable Serializable]
184 for i
in [0..len
.to_i
[ do map
[read_msgpack
] = read_msgpack
188 # Read the content of an array of `len` items
189 private fun read_msgpack_array_data
(len
: Int): Array[nullable Serializable]
191 return [for i
in [0..len
[ do read_msgpack
]
194 # Read the content of a *fixext* of `len` bytes
197 # var reader = new BytesReader(b"\xC7\x03\x0A\x0B\x0C\x0D")
198 # var ext = reader.read_msgpack
199 # assert ext isa MsgPackExt
200 # assert ext.typ == 0x0Au8
201 # assert ext.data == b"\x0B\x0C\x0D"
203 private fun read_msgpack_fixext_data
(len
: Int): MsgPackExt
205 var exttyp
= read_byte
or else 0u8
206 var data
= read_bytes
(len
)
207 return new MsgPackExt(exttyp
, data
)
210 # Read the content of a dynamic *ext* including the length on `len_len` bytes
211 private fun read_msgpack_ext_data
(len_len
: Int): MsgPackExt
213 var len
= read_bytes
(len_len
).to_i
214 return read_msgpack_fixext_data
(len
)