A Stream that can be read from

Introduced properties

fun append_line_to(s: Buffer)

core :: Reader :: append_line_to

Read a string until the end of the line and append it to s.
fun deserialize_msgpack(static_type: nullable String): nullable Object

core :: Reader :: deserialize_msgpack

Deserialize full Nit nullable Object from MessagePack formated data
fun each_line: LineIterator

core :: Reader :: each_line

Return an iterator that read each line.
fun eof: Bool

core :: Reader :: eof

Is there something to read.
protected abstract fun raw_read_byte: Int

core :: Reader :: raw_read_byte

Read a byte directly from the underlying stream, without
protected fun raw_read_bytes(buf: CString, max: Int): Int

core :: Reader :: raw_read_bytes

Read at most max bytes from the underlying stream into buf,
fun read(i: Int): String

core :: Reader :: read

Reads a String of at most i length
fun read_all: String

core :: Reader :: read_all

Read all the stream until the eof.
fun read_all_bytes: Bytes

core :: Reader :: read_all_bytes

Read all the stream until the eof.
fun read_bits: Array[Bool]

core :: Reader :: read_bits

Get an Array of 8 Bool by reading a single byte
fun read_block: String

core :: Reader :: read_block

Read the length as a 64 bits integer, then the content of the block
fun read_bool: Bool

core :: Reader :: read_bool

Read a single byte and return true if its value is different than 0
fun read_byte: Int

core :: Reader :: read_byte

Reads a byte. Returns a negative value on error
fun read_bytes(max: Int): Bytes

core :: Reader :: read_bytes

Reads up to max bytes from source
fun read_bytes_to_cstring(bytes: CString, max: Int): Int

core :: Reader :: read_bytes_to_cstring

Reads up to max bytes from source and stores them in bytes
fun read_char: nullable Char

core :: Reader :: read_char

Reads a character. Returns null on EOF or timeout
fun read_double: Float

core :: Reader :: read_double

Read a floating point on 64 bits and return it as a Float
fun read_float: Float

core :: Reader :: read_float

Read a floating point on 32 bits and return it as a Float
fun read_int64: Int

core :: Reader :: read_int64

Read a signed integer on 64 bits and return is an Int
fun read_line: String

core :: Reader :: read_line

Read a string until the end of the line.
fun read_lines: Array[String]

core :: Reader :: read_lines

Read all the lines until the eof.
fun read_msgpack: nullable Serializable

core :: Reader :: read_msgpack

Read the next MessagePack object and return it as a simple Nit object
fun read_nonwhitespace: nullable Char

core :: Reader :: read_nonwhitespace

Skip whitespace characters (if any) then return the following non-whitespace character.
fun read_string: String

core :: Reader :: read_string

Read a null terminated string
fun read_word: String

core :: Reader :: read_word

Read the next sequence of non whitespace characters.

Redefined properties

redef type SELF: Reader

core $ Reader :: SELF

Type of this instance, automatically specialized in every class

All properties

fun !=(other: nullable Object): Bool

core :: Object :: !=

Have self and other different values?
fun ==(other: nullable Object): Bool

core :: Object :: ==

Have self and other the same value?
type CLASS: Class[SELF]

core :: Object :: CLASS

The type of the class of self.
type SELF: Object

core :: Object :: SELF

Type of this instance, automatically specialized in every class
fun append_line_to(s: Buffer)

core :: Reader :: append_line_to

Read a string until the end of the line and append it to s.
fun big_endian: Bool

binary :: BinaryStream :: big_endian

Use the big-endian convention? otherwise use little-endian.
fun big_endian=(big_endian: Bool)

binary :: BinaryStream :: big_endian=

Use the big-endian convention? otherwise use little-endian.
protected fun class_factory(name: String): CLASS

core :: Object :: class_factory

Implementation used by get_class to create the specific class.
fun class_name: String

core :: Object :: class_name

The class name of the object.
abstract fun close

core :: Stream :: close

close the stream
fun codec: Codec

core :: Stream :: codec

Codec used to transform raw data to text
fun codec=(c: Codec)

core :: Stream :: codec=

Change the codec for this stream.
fun deserialize_msgpack(static_type: nullable String): nullable Object

core :: Reader :: deserialize_msgpack

Deserialize full Nit nullable Object from MessagePack formated data
fun each_line: LineIterator

core :: Reader :: each_line

Return an iterator that read each line.
fun eof: Bool

core :: Reader :: eof

Is there something to read.
fun finish

core :: Stream :: finish

Post-work hook.
fun get_class: CLASS

core :: Object :: get_class

The meta-object representing the dynamic type of self.
fun hash: Int

core :: Object :: hash

The hash code of the object.
init init

core :: Object :: init

fun inspect: String

core :: Object :: inspect

Developer readable representation of self.
protected fun inspect_head: String

core :: Object :: inspect_head

Return "CLASSNAME:#OBJECTID".
intern fun is_same_instance(other: nullable Object): Bool

core :: Object :: is_same_instance

Return true if self and other are the same instance (i.e. same identity).
fun is_same_serialized(other: nullable Object): Bool

core :: Object :: is_same_serialized

Is self the same as other in a serialization context?
intern fun is_same_type(other: Object): Bool

core :: Object :: is_same_type

Return true if self and other have the same dynamic type.
fun last_error: nullable IOError

core :: Stream :: last_error

Error produced by the file stream
protected fun last_error=(last_error: nullable IOError)

core :: Stream :: last_error=

Error produced by the file stream
protected fun lookahead: CString

core :: Stream :: lookahead

Lookahead buffer for codecs
protected fun lookahead=(lookahead: CString)

core :: Stream :: lookahead=

Lookahead buffer for codecs
protected fun lookahead_capacity: Int

core :: Stream :: lookahead_capacity

Capacity of the lookahead
protected fun lookahead_capacity=(lookahead_capacity: Int)

core :: Stream :: lookahead_capacity=

Capacity of the lookahead
protected fun lookahead_length: Int

core :: Stream :: lookahead_length

Current occupation of the lookahead
protected fun lookahead_length=(lookahead_length: Int)

core :: Stream :: lookahead_length=

Current occupation of the lookahead
intern fun object_id: Int

core :: Object :: object_id

An internal hash code for the object based on its identity.
fun output

core :: Object :: output

Display self on stdout (debug only).
intern fun output_class_name

core :: Object :: output_class_name

Display class name on stdout (debug only).
protected abstract fun raw_read_byte: Int

core :: Reader :: raw_read_byte

Read a byte directly from the underlying stream, without
protected fun raw_read_bytes(buf: CString, max: Int): Int

core :: Reader :: raw_read_bytes

Read at most max bytes from the underlying stream into buf,
fun read(i: Int): String

core :: Reader :: read

Reads a String of at most i length
fun read_all: String

core :: Reader :: read_all

Read all the stream until the eof.
fun read_all_bytes: Bytes

core :: Reader :: read_all_bytes

Read all the stream until the eof.
fun read_bits: Array[Bool]

core :: Reader :: read_bits

Get an Array of 8 Bool by reading a single byte
fun read_block: String

core :: Reader :: read_block

Read the length as a 64 bits integer, then the content of the block
fun read_bool: Bool

core :: Reader :: read_bool

Read a single byte and return true if its value is different than 0
fun read_byte: Int

core :: Reader :: read_byte

Reads a byte. Returns a negative value on error
fun read_bytes(max: Int): Bytes

core :: Reader :: read_bytes

Reads up to max bytes from source
fun read_bytes_to_cstring(bytes: CString, max: Int): Int

core :: Reader :: read_bytes_to_cstring

Reads up to max bytes from source and stores them in bytes
fun read_char: nullable Char

core :: Reader :: read_char

Reads a character. Returns null on EOF or timeout
fun read_double: Float

core :: Reader :: read_double

Read a floating point on 64 bits and return it as a Float
fun read_float: Float

core :: Reader :: read_float

Read a floating point on 32 bits and return it as a Float
fun read_int64: Int

core :: Reader :: read_int64

Read a signed integer on 64 bits and return is an Int
fun read_line: String

core :: Reader :: read_line

Read a string until the end of the line.
fun read_lines: Array[String]

core :: Reader :: read_lines

Read all the lines until the eof.
fun read_msgpack: nullable Serializable

core :: Reader :: read_msgpack

Read the next MessagePack object and return it as a simple Nit object
fun read_nonwhitespace: nullable Char

core :: Reader :: read_nonwhitespace

Skip whitespace characters (if any) then return the following non-whitespace character.
fun read_string: String

core :: Reader :: read_string

Read a null terminated string
fun read_word: String

core :: Reader :: read_word

Read the next sequence of non whitespace characters.
fun serialization_hash: Int

core :: Object :: serialization_hash

Hash value use for serialization
protected fun set_codec(codec: Codec)

core :: Stream :: set_codec

Codec used to transform raw data to text
fun start

core :: Stream :: start

Pre-work hook.
intern fun sys: Sys

core :: Object :: sys

Return the global sys object, the only instance of the Sys class.
abstract fun to_jvalue(env: JniEnv): JValue

core :: Object :: to_jvalue

fun to_s: String

core :: Object :: to_s

User readable representation of self.
protected fun write_buffer: CString

core :: Stream :: write_buffer

Buffer for writing data to a stream
protected fun write_buffer=(write_buffer: CString)

core :: Stream :: write_buffer=

Buffer for writing data to a stream
package_diagram core::Reader Reader binary::BinaryStream BinaryStream core::Reader->binary::BinaryStream core::Stream Stream binary::BinaryStream->core::Stream ...core::Stream ... ...core::Stream->core::Stream core::PollableReader PollableReader core::PollableReader->core::Reader core::Duplex Duplex core::Duplex->core::Reader core::BytesReader BytesReader core::BytesReader->core::Reader core::ProcessReader ProcessReader core::ProcessReader->core::Reader core::ReaderProtocol ReaderProtocol core::ReaderProtocol->core::Reader filter_stream::FilterReader FilterReader filter_stream::FilterReader->core::Reader core::FileReader FileReader core::FileReader->core::PollableReader socket::TCPStream TCPStream socket::TCPStream->core::PollableReader socket::TCPStream->core::Duplex websocket::WebsocketConnection WebsocketConnection websocket::WebsocketConnection->core::PollableReader core::FileReader... ... core::FileReader...->core::FileReader socket::TCPStream... ... socket::TCPStream...->socket::TCPStream websocket::WebsocketConnection... ... websocket::WebsocketConnection...->websocket::WebsocketConnection core::ProcessDuplex ProcessDuplex core::ProcessDuplex->core::Duplex core::ProcessDuplex->core::ProcessReader core::DuplexProtocol DuplexProtocol core::DuplexProtocol->core::Duplex core::DuplexProtocol->core::ReaderProtocol core::ProcessDuplex... ... core::ProcessDuplex...->core::ProcessDuplex core::DuplexProtocol... ... core::DuplexProtocol...->core::DuplexProtocol core::StringReader StringReader core::StringReader->core::BytesReader core::StringReader... ... core::StringReader...->core::StringReader filter_stream::StreamCat StreamCat filter_stream::StreamCat->filter_stream::FilterReader filter_stream::StreamCat... ... filter_stream::StreamCat...->filter_stream::StreamCat

Ancestors

interface Object

core :: Object

The root of the class hierarchy.
abstract class Stream

core :: Stream

Any kind of stream to read/write/both to or from a source

Parents

abstract class BinaryStream

binary :: BinaryStream

A stream of binary data

Children

class BytesReader

core :: BytesReader

Read from bytes in memory
abstract class Duplex

core :: Duplex

A Stream that can be written to and read from
abstract class PollableReader

core :: PollableReader

Reader capable of declaring if readable without blocking
class ProcessReader

core :: ProcessReader

Process on which the stdout is readable like a Reader
class ReaderProtocol

core :: ReaderProtocol

Reader decorator over a read-capable stream

Descendants

class DuplexProtocol

core :: DuplexProtocol

Reader/Writer decorator over a duplex-capable stream
class FileReader

core :: FileReader

Stream that can read from a File
class ProcessDuplex

core :: ProcessDuplex

Process on which stdout can be read and stdin can be written to like a Duplex
class Stdin

core :: Stdin

Standard input stream.
class StringReader

core :: StringReader

Stream reading from a String source
class TCPStream

socket :: TCPStream

Simple communication stream with a remote socket
class WebsocketConnection

websocket :: WebsocketConnection

Connection to a websocket client

Class definitions

core $ Reader
# A `Stream` that can be read from
abstract class Reader
	super Stream

	# Read a byte directly from the underlying stream, without
	# considering any eventual buffer
	protected fun raw_read_byte: Int is abstract

	# Read at most `max` bytes from the underlying stream into `buf`,
	# without considering any eventual buffer
	#
	# Returns how many bytes were read
	protected fun raw_read_bytes(buf: CString, max: Int): Int do
		var rd = 0
		for i in [0 .. max[ do
			var b = raw_read_byte
			if b < 0 then break
			buf[i] = b
			rd += 1
		end
		return rd
	end

	# Reads a character. Returns `null` on EOF or timeout
	#
	# Returns unicode replacement character '�' if an
	# invalid byte sequence is read.
	#
	# `read_char` may block if:
	#
	# * No byte could be read from the current buffer
	# * An incomplete char is partially read, and more bytes are
	#   required for full decoding.
	fun read_char: nullable Char do
		if eof then return null
		var cod = codec
		var codet_sz = cod.codet_size
		var lk = lookahead
		var llen = lookahead_length
		if llen < codet_sz then
			llen += raw_read_bytes(lk.fast_cstring(llen), codet_sz - llen)
		end
		if llen < codet_sz then
			lookahead_length = 0
			return 0xFFFD.code_point
		end
		var ret = cod.is_valid_char(lk, codet_sz)
		var max_llen = cod.max_lookahead
		while ret == 1 and llen < max_llen do
			var rd = raw_read_bytes(lk.fast_cstring(llen), codet_sz)
			if rd < codet_sz then
				llen -= codet_sz
				if llen > 0 then
					lookahead.lshift(codet_sz, llen, codet_sz)
				end
				lookahead_length = llen.max(0)
				return 0xFFFD.code_point
			end
			llen += codet_sz
			ret = cod.is_valid_char(lk, llen)
		end
		if ret == 0 then
			var c = cod.decode_char(lk)
			var clen = c.u8char_len
			llen -= clen
			if llen > 0 then
				lookahead.lshift(clen, llen, clen)
			end
			lookahead_length = llen
			return c
		end
		if ret == 2 or ret == 1 then
			llen -= codet_sz
			if llen > 0 then
				lookahead.lshift(codet_sz, llen, codet_sz)
			end
			lookahead_length = llen
			return 0xFFFD.code_point
		end
		# Should not happen if the decoder works properly
		var arr = new Array[Object]
		arr.push "Decoder error: could not decode nor recover from byte sequence ["
		for i in [0 .. llen[ do
			arr.push lk[i]
			arr.push ", "
		end
		arr.push "]"
		var err = new IOError(arr.plain_to_s)
		err.cause = last_error
		last_error = err
		return 0xFFFD.code_point
	end

	# Reads a byte. Returns a negative value on error
	fun read_byte: Int do
		var llen = lookahead_length
		if llen == 0 then return raw_read_byte
		var lk = lookahead
		var b = lk[0].to_i
		if llen == 1 then
			lookahead_length = 0
		else
			lk.lshift(1, llen - 1, 1)
			lookahead_length -= 1
		end
		return b
	end

	# Reads a String of at most `i` length
	fun read(i: Int): String do
		assert i >= 0
		var cs = new CString(i)
		var rd = read_bytes_to_cstring(cs, i)
		if rd < 0 then return ""
		return codec.decode_string(cs, rd)
	end

	# Reads up to `max` bytes from source
	fun read_bytes(max: Int): Bytes do
		assert max >= 0
		var cs = new CString(max)
		var rd = read_bytes_to_cstring(cs, max)
		return new Bytes(cs, rd, max)
	end

	# Reads up to `max` bytes from source and stores them in `bytes`
	fun read_bytes_to_cstring(bytes: CString, max: Int): Int do
		var llen = lookahead_length
		if llen == 0 then return raw_read_bytes(bytes, max)
		var rd = max.min(llen)
		var lk = lookahead
		lk.copy_to(bytes, rd, 0, 0)
		if rd < llen then
			lk.lshift(rd, llen - rd, rd)
			lookahead_length -= rd
		else
			lookahead_length = 0
		end
		return rd + raw_read_bytes(bytes.fast_cstring(rd), max - rd)
	end

	# Read a string until the end of the line.
	#
	# The line terminator '\n' and '\r\n', if any, is removed in each line.
	#
	# ~~~
	# var txt = "Hello\n\nWorld\n"
	# var i = new StringReader(txt)
	# assert i.read_line == "Hello"
	# assert i.read_line == ""
	# assert i.read_line == "World"
	# assert i.eof
	# ~~~
	#
	# Only LINE FEED (`\n`), CARRIAGE RETURN & LINE FEED (`\r\n`), and
	# the end or file (EOF) is considered to delimit the end of lines.
	# CARRIAGE RETURN (`\r`) alone is not used for the end of line.
	#
	# ~~~
	# var txt2 = "Hello\r\n\n\rWorld"
	# var i2 = new StringReader(txt2)
	# assert i2.read_line == "Hello"
	# assert i2.read_line == ""
	# assert i2.read_line == "\rWorld"
	# assert i2.eof
	# ~~~
	#
	# NOTE: Use `append_line_to` if the line terminator needs to be preserved.
	fun read_line: String
	do
		if last_error != null then return ""
		if eof then return ""
		var s = new FlatBuffer
		append_line_to(s)
		return s.to_s.chomp
	end

	# Read all the lines until the eof.
	#
	# The line terminator '\n' and `\r\n` is removed in each line,
	#
	# ~~~
	# var txt = "Hello\n\nWorld\n"
	# var i = new StringReader(txt)
	# assert i.read_lines == ["Hello", "", "World"]
	# ~~~
	#
	# This method is more efficient that splitting
	# the result of `read_all`.
	#
	# NOTE: SEE `read_line` for details.
	fun read_lines: Array[String]
	do
		var res = new Array[String]
		while not eof do
			res.add read_line
		end
		return res
	end

	# Return an iterator that read each line.
	#
	# The line terminator '\n' and `\r\n` is removed in each line,
	# The line are read with `read_line`. See this method for details.
	#
	# ~~~
	# var txt = "Hello\n\nWorld\n"
	# var i = new StringReader(txt)
	# assert i.each_line.to_a == ["Hello", "", "World"]
	# ~~~
	#
	# Unlike `read_lines` that read all lines at the call, `each_line` is lazy.
	# Therefore, the stream should no be closed until the end of the stream.
	#
	# ~~~
	# i = new StringReader(txt)
	# var el = i.each_line
	#
	# assert el.item == "Hello"
	# el.next
	# assert el.item == ""
	# el.next
	#
	# i.close
	#
	# assert not el.is_ok
	# # closed before "world" is read
	# ~~~
	fun each_line: LineIterator do return new LineIterator(self)

	# Read all the stream until the eof.
	#
	# The content of the file is returned as a String.
	#
	# ~~~
	# var txt = "Hello\n\nWorld\n"
	# var i = new StringReader(txt)
	# assert i.read_all == txt
	# ~~~
	fun read_all: String do
		var s = read_all_bytes
		var slen = s.length
		if slen == 0 then return ""
		return codec.decode_string(s.items, s.length)
	end

	# Read all the stream until the eof.
	#
	# The content of the file is returned verbatim.
	fun read_all_bytes: Bytes
	do
		if last_error != null then return new Bytes.empty
		var s = new Bytes.empty
		var buf = new CString(4096)
		while not eof do
			var rd = read_bytes_to_cstring(buf, 4096)
			s.append_ns(buf, rd)
		end
		return s
	end

	# Read a string until the end of the line and append it to `s`.
	#
	# Unlike `read_line` and other related methods,
	# the line terminator '\n', if any, is preserved in each line.
	# Use the method `Text::chomp` to safely remove it.
	#
	# ~~~
	# var txt = "Hello\n\nWorld\n"
	# var i = new StringReader(txt)
	# var b = new FlatBuffer
	# i.append_line_to(b)
	# assert b == "Hello\n"
	# i.append_line_to(b)
	# assert b == "Hello\n\n"
	# i.append_line_to(b)
	# assert b == txt
	# assert i.eof
	# ~~~
	#
	# If `\n` is not present at the end of the result, it means that
	# a non-eol terminated last line was returned.
	#
	# ~~~
	# var i2 = new StringReader("hello")
	# assert not i2.eof
	# var b2 = new FlatBuffer
	# i2.append_line_to(b2)
	# assert b2 == "hello"
	# assert i2.eof
	# ~~~
	#
	# NOTE: The single character LINE FEED (`\n`) delimits the end of lines.
	# Therefore CARRIAGE RETURN & LINE FEED (`\r\n`) is also recognized.
	fun append_line_to(s: Buffer)
	do
		if last_error != null then return
		loop
			var x = read_char
			if x == null then
				if eof then return
			else
				s.chars.push(x)
				if x == '\n' then return
			end
		end
	end

	# Is there something to read.
	# This function returns 'false' if there is something to read.
	fun eof: Bool do
		if lookahead_length > 0 then return false
		lookahead_length = raw_read_bytes(lookahead, 1)
		return lookahead_length <= 0
	end

	# Read the next sequence of non whitespace characters.
	#
	# Leading whitespace characters are skipped.
	# The first whitespace character that follows the result is consumed.
	#
	# An empty string is returned if the end of the file or an error is encounter.
	#
	# ~~~
	# var w = new StringReader(" Hello, \n\t World!")
	# assert w.read_word == "Hello,"
	# assert w.read_char == '\n'
	# assert w.read_word == "World!"
	# assert w.read_word == ""
	# ~~~
	#
	# `Char::is_whitespace` determines what is a whitespace.
	fun read_word: String
	do
		var buf = new FlatBuffer
		var c = read_nonwhitespace
		if c != null then
			buf.add(c)
			while not eof do
				c = read_char
				if c == null then break
				if c.is_whitespace then break
				buf.add(c)
			end
		end
		var res = buf.to_s
		return res
	end

	# Skip whitespace characters (if any) then return the following non-whitespace character.
	#
	# Returns the code point of the character.
	# Returns `null` on end of file or error.
	#
	# In fact, this method works like `read_char` except it skips whitespace.
	#
	# ~~~
	# var w = new StringReader(" \nab\tc")
	# assert w.read_nonwhitespace == 'a'
	# assert w.read_nonwhitespace == 'b'
	# assert w.read_nonwhitespace == 'c'
	# assert w.read_nonwhitespace == null
	# ~~~
	#
	# `Char::is_whitespace` determines what is a whitespace.
	fun read_nonwhitespace: nullable Char
	do
		var c: nullable Char = null
		while not eof do
			c = read_char
			if c == null or not c.is_whitespace then break
		end
		return c
	end
end
lib/core/stream.nit:108,1--482,3

binary :: binary $ Reader
redef abstract class Reader
	super BinaryStream

	# Read a single byte and return `true` if its value is different than 0
	#
	# Returns `false` when an error is pending (`last_error != null`).
	fun read_bool: Bool do return read_byte > 0

	# Get an `Array` of 8 `Bool` by reading a single byte
	#
	# To be used with `BinaryWriter::write_bits`.
	#
	# Returns an array of `false` when an error is pending (`last_error != null`).
	fun read_bits: Array[Bool]
	do
		var int = read_byte
		if int < 0 then return new Array[Bool]
		var arr = new Array[Bool]
		for i in [7 .. 0].step(-1) do
			arr.push(((int >> i) & 1) != 0)
		end
		return arr
	end

	# Read a null terminated string
	#
	# To be used with `Writer::write_string`.
	#
	# Returns a truncated string when an error is pending (`last_error != null`).
	fun read_string: String
	do
		var buf = new Bytes.empty
		loop
			var byte = read_byte
			if byte <= 0 then
				return buf.to_s
			end
			buf.add byte
		end
	end

	# Read the length as a 64 bits integer, then the content of the block
	#
	# To be used with `Writer::write_block`.
	#
	# Returns a truncated string when an error is pending (`last_error != null`).
	fun read_block: String
	do
		var length = read_int64
		if length == 0 then return ""
		return read_bytes(length).to_s
	end

	# Read a floating point on 32 bits and return it as a `Float`
	#
	# Using this format may result in a loss of precision as it uses less bits
	# than Nit `Float`.
	#
	# Returns `0.0` when an error is pending (`last_error != null`).
	fun read_float: Float
	do
		if last_error != null then return 0.0

		var b0 = read_byte
		var b1 = read_byte
		var b2 = read_byte
		var b3 = read_byte

		# Check for error, `last_error` is set by `read_byte`
		if b0 < 0 or b1 < 0 or b2 < 0 or b3 < 0 then return 0.0

		return native_read_float(b0, b1, b2, b3, big_endian)
	end

	# Utility for `read_float`
	private fun native_read_float(b0, b1, b2, b3: Int, big_endian: Bool): Float `{
		union {
			unsigned char b[4];
			float val;
			uint32_t conv;
		} u;

		u.b[0] = b0;
		u.b[1] = b1;
		u.b[2] = b2;
		u.b[3] = b3;

		if (big_endian)
			u.conv = be32toh(u.conv);
		else u.conv = le32toh(u.conv);

		return u.val;
	`}

	# Read a floating point on 64 bits and return it as a `Float`
	#
	# Returns `0.0` when an error is pending (`last_error != null`).
	fun read_double: Float
	do
		if last_error != null then return 0.0

		var b0 = read_byte
		var b1 = read_byte
		var b2 = read_byte
		var b3 = read_byte
		var b4 = read_byte
		var b5 = read_byte
		var b6 = read_byte
		var b7 = read_byte

		# Check for error, `last_error` is set by `read_byte`
		if b0 < 0 or b1 < 0 or b2 < 0 or b3 < 0 or
		   b4 < 0 or b5 < 0 or b6 < 0 or b7 < 0 then return 0.0

		return native_read_double(b0, b1, b2, b3, b4, b5, b6, b7, big_endian)
	end

	# Utility for `read_double`
	private fun native_read_double(b0, b1, b2, b3, b4, b5, b6, b7: Int, big_endian: Bool): Float `{
		union {
			unsigned char b[8];
			double val;
			uint64_t conv;
		} u;

		u.b[0] = b0;
		u.b[1] = b1;
		u.b[2] = b2;
		u.b[3] = b3;
		u.b[4] = b4;
		u.b[5] = b5;
		u.b[6] = b6;
		u.b[7] = b7;

		if (big_endian)
			u.conv = be64toh(u.conv);
		else u.conv = le64toh(u.conv);

		return u.val;
	`}

	# Read a signed integer on 64 bits and return is an `Int`
	#
	# Using this format may result in a loss of precision as the length of a
	# Nit `Int` may be less than 64 bits on some platforms.
	#
	# Returns `0` when an error is pending (`last_error != null`).
	fun read_int64: Int
	do
		if last_error != null then return 0

		var b0 = read_byte
		var b1 = read_byte
		var b2 = read_byte
		var b3 = read_byte
		var b4 = read_byte
		var b5 = read_byte
		var b6 = read_byte
		var b7 = read_byte

		# Check for error, `last_error` is set by `read_byte`
		if b0 < 0 or b1 < 0 or b2 < 0 or b3 < 0 or
		   b4 < 0 or b5 < 0 or b6 < 0 or b7 < 0 then return 0

		return native_read_int64(b0, b1, b2, b3, b4, b5, b6, b7, big_endian)
	end

	# Utility for `read_int64`
	private fun native_read_int64(b0, b1, b2, b3, b4, b5, b6, b7: Int, big_endian: Bool): Int `{
		union {
			unsigned char b[8];
			int64_t val;
			uint64_t conv;
		} u;

		u.b[0] = b0;
		u.b[1] = b1;
		u.b[2] = b2;
		u.b[3] = b3;
		u.b[4] = b4;
		u.b[5] = b5;
		u.b[6] = b6;
		u.b[7] = b7;

		if (big_endian)
			u.conv = be64toh(u.conv);
		else u.conv = le64toh(u.conv);

		return u.val;
	`}
end
lib/binary/binary.nit:150,1--340,3

msgpack :: read $ Reader
redef class Reader

	# 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

	# Read the content of a map, `len` keys and values
	private fun read_msgpack_map_data(len: Int): Map[nullable Serializable, nullable Serializable]
	do
		var map = new Map[nullable Serializable, nullable Serializable]
		for i in [0..len.to_i[ do map[read_msgpack] = read_msgpack
		return map
	end

	# Read the content of an array of `len` items
	private fun read_msgpack_array_data(len: Int): Array[nullable Serializable]
	do
		return [for i in [0..len[ do read_msgpack]
	end

	# Read the content of a *fixext* of `len` bytes
	#
	# ~~~
	# var reader = new BytesReader(b"\xC7\x03\x0A\x0B\x0C\x0D")
	# var ext = reader.read_msgpack
	# assert ext isa MsgPackExt
	# assert ext.typ == 0x0a
	# assert ext.data == b"\x0B\x0C\x0D"
	# ~~~
	private fun read_msgpack_fixext_data(len: Int): MsgPackExt
	do
		var exttyp = read_byte
		if exttyp < 0 then exttyp = 0
		var data = read_bytes(len)
		return new MsgPackExt(exttyp, data)
	end

	# Read the content of a dynamic *ext* including the length on `len_len` bytes
	private fun read_msgpack_ext_data(len_len: Int): MsgPackExt
	do
		var len = read_bytes(len_len).to_i
		return read_msgpack_fixext_data(len)
	end
end
lib/msgpack/read.nit:23,1--194,3

msgpack :: serialization_read $ Reader
redef class Reader

	# Deserialize full Nit `nullable Object` from MessagePack formated data
	#
	# This method use metadata in the MessagePack source to recreate full
	# Nit objects serialized by `Writer::serialize_msgpack` or
	# `MsgPackSerializer`.
	#
	# The dynamic type of the deserialized object can be limited to `static_type`.
	#
	# Warning: Deserialization errors are reported with `print_error`,
	# the returned object may be partial or fall back on `null`.
	# To handle the errors programmatically, use a `MsgPackDeserializer`.
	fun deserialize_msgpack(static_type: nullable String): nullable Object
	do
		var deserializer = new MsgPackDeserializer(self)
		var res = deserializer.deserialize(static_type)

		if deserializer.errors.length == 1 then
			print_error deserializer.errors.join("")
		else if deserializer.errors.not_empty then
			print_error "Deserialization Errors:\n* {deserializer.errors.join("\n* ")}"
		end

		return res
	end
end
lib/msgpack/serialization_read.nit:51,1--77,3