Read the next MessagePack object and return it as a simple Nit object

The return value is composed of:

  • the simple types null, Bool, Int, Float, String and Bytes,
  • collections of simple Nit objects Array[nullable Serializable] and Map[nullable Serializable, nullable Serializable],
  • and MsgPackExt for custom MessagePack ext data.

This method reads plain MessagePack data, as written by MsgPackSerializer when plain_msgpack == true. To deserialize full Nit objects from MessagePack with metadata use Reader::deserialize_msgpack.

Property definitions

msgpack :: read $ Reader :: read_msgpack
	# Read the next MessagePack object and return it as a simple Nit object
	#
	# The return value is composed of:
	# * the simple types `null`, `Bool`, `Int`, `Float`, `String` and `Bytes`,
	# * collections of simple Nit objects `Array[nullable Serializable]`
	#   and `Map[nullable Serializable, nullable Serializable]`,
	# * and `MsgPackExt` for custom MessagePack *ext* data.
	#
	# This method reads plain MessagePack data, as written by `MsgPackSerializer`
	# when `plain_msgpack == true`. To deserialize full Nit objects from
	# MessagePack with metadata use `Reader::deserialize_msgpack`.
	fun read_msgpack: nullable Serializable
	do
		if last_error != null then return 0

		var typ = read_byte
		if typ < 0 then
			# Error, return default `null`
			return null

		else if typ & 0b1000_0000 == 0 or typ & 0b1110_0000 == 0b1110_0000 then
			# fixint
			var bytes = new Bytes.with_capacity(1)
			bytes.add typ
			return bytes.to_i(signed=true)

		else if typ & 0b1111_0000 == 0b1000_0000 then
			# fixmap
			var len = typ & 0b0000_1111
			return read_msgpack_map_data(len.to_i)

		else if typ & 0b1111_0000 == 0b1001_0000 then
			# fixarray
			var len = typ & 0b0000_1111
			return read_msgpack_array_data(len.to_i)

		else if typ & 0b1110_0000 == 0b1010_0000 then
			# fixstr
			var len = typ & 0b0001_1111
			return read_bytes(len.to_i).to_s

		else if typ == 0xC0 then
			return null
		else if typ == 0xC2 then
			return false
		else if typ == 0xC3 then
			return true

		else if typ >= 0xCC and typ <= 0xCF then
			# uint8, 16, 32 and 64
			var len = 1 << (typ - 0xCC)
			return read_bytes(len).to_i

		else if typ >= 0xD0 and typ <= 0xD3 then
			# int8, 16, 32 and 64
			var len = 1 << (typ - 0xD0)
			return read_bytes(len).to_i(true)

		else if typ == 0xCA then
			return read_float
		else if typ == 0xCB then
			return read_double

		else if typ >= 0xD9 and typ <= 0xDB then
			# str8, 16 and 32
			var len_ln = 1 << (typ - 0xD9)
			var bf = read_bytes(len_ln)
			var len = bf.to_i
			if len < 0 then return null
			var rd_buf = read_bytes(len)
			if rd_buf.length != len then
				# Bad formatted message.
				return null
			end
			return rd_buf.to_s

		else if typ >= 0xC4 and typ <= 0xC6 then
			# bin8, 16 or 32
			var len_ln = 1 << (typ - 0xC4)
			var bf = read_bytes(len_ln)
			var len = bf.to_i
			if len < 0 then return null
			var rd_buf = read_bytes(len)
			if rd_buf.length != len then
				# Bad formatted message.
				return null
			end
			return rd_buf

		else if typ == 0xDC or typ == 0xDD then
			# array16 and array32
			var len_ln = 2 << (typ - 0xDC)
			var lenbuf = read_bytes(len_ln)
			return read_msgpack_array_data(lenbuf.to_i)

		else if typ == 0xDE or typ == 0xDF then
			# map16 and map32
			var len_ln = 2 << (typ - 0xDE)
			var lenbuf = read_bytes(len_ln)
			return read_msgpack_map_data(lenbuf.to_i)

		else if typ == 0xD4 then
			# fixext1
			return read_msgpack_fixext_data(1)
		else if typ == 0xD5 then
			# fixext2
			return read_msgpack_fixext_data(2)
		else if typ == 0xD6 then
			# fixext4
			return read_msgpack_fixext_data(4)
		else if typ == 0xD7 then
			# fixext8
			return read_msgpack_fixext_data(8)
		else if typ == 0xD8 then
			# fixext16
			return read_msgpack_fixext_data(16)

		else if typ == 0xC7 then
			# ext1
			return read_msgpack_ext_data(1)
		else if typ == 0xC8 then
			# ext2
			return read_msgpack_ext_data(2)
		else if typ == 0xC9 then
			# ext4
			return read_msgpack_ext_data(4)
		end

		print_error "MessagePack Warning: Found no match for typ {typ.to_base(16)} / 0b{typ.to_base(2)}"
		return null
	end
lib/msgpack/read.nit:25,2--155,4