Low-level write in MessagePack format to Writer streams

Redefined classes

redef abstract class Writer

msgpack :: write $ Writer

A Stream that can be written to

All class definitions

redef abstract class Writer

msgpack :: write $ Writer

A Stream that can be written to
package_diagram msgpack::write write binary binary msgpack::write->binary core core binary->core ...core ... ...core->core msgpack::serialization_write serialization_write msgpack::serialization_write->msgpack::write msgpack::msgpack msgpack msgpack::msgpack->msgpack::serialization_write msgpack::msgpack... ... msgpack::msgpack...->msgpack::msgpack

Ancestors

module abstract_collection

core :: abstract_collection

Abstract collection classes and services.
module abstract_text

core :: abstract_text

Abstract class for manipulation of sequences of characters
module array

core :: array

This module introduces the standard array structure.
module bitset

core :: bitset

Services to handle BitSet
module bytes

core :: bytes

Services for byte streams and arrays
module circular_array

core :: circular_array

Efficient data structure to access both end of the sequence.
module codec_base

core :: codec_base

Base for codecs to use with streams
module codecs

core :: codecs

Group module for all codec-related manipulations
module collection

core :: collection

This module define several collection classes.
module core

core :: core

Standard classes and methods used by default by Nit programs and libraries.
module environ

core :: environ

Access to the environment variables of the process
module error

core :: error

Standard error-management infrastructure.
module exec

core :: exec

Invocation and management of operating system sub-processes.
module file

core :: file

File manipulations (create, read, write, etc.)
module fixed_ints

core :: fixed_ints

Basic integers of fixed-precision
module fixed_ints_text

core :: fixed_ints_text

Text services to complement fixed_ints
module flat

core :: flat

All the array-based text representations
module gc

core :: gc

Access to the Nit internal garbage collection mechanism
module hash_collection

core :: hash_collection

Introduce HashMap and HashSet.
module iso8859_1

core :: iso8859_1

Codec for ISO8859-1 I/O
module kernel

core :: kernel

Most basic classes and methods.
module list

core :: list

This module handle double linked lists
module math

core :: math

Mathematical operations
module native

core :: native

Native structures for text and bytes
module numeric

core :: numeric

Advanced services for Numeric types
module protocol

core :: protocol

module queue

core :: queue

Queuing data structures and wrappers
module range

core :: range

Module for range of discrete objects.
module re

core :: re

Regular expression support for all services based on Pattern
module ropes

core :: ropes

Tree-based representation of a String.
module sorter

core :: sorter

This module contains classes used to compare things and sorts arrays.
module stream

core :: stream

Input and output streams of characters
module text

core :: text

All the classes and methods related to the manipulation of text entities
module time

core :: time

Management of time and dates
module union_find

core :: union_find

union–find algorithm using an efficient disjoint-set data structure
module utf8

core :: utf8

Codec for UTF-8 I/O

Parents

module binary

binary :: binary

Read and write binary data with any Reader and Writer

Children

module serialization_write

msgpack :: serialization_write

Serialize full Nit objects to MessagePack format

Descendants

module a_star-m

a_star-m

module client

gamnit :: client

Client-side network services for games and such
module common

gamnit :: common

Services common to the client and server modules
module msgpack

msgpack :: msgpack

MessagePack, an efficient binary serialization format
module network

gamnit :: network

Easy client/server logic for games and simple distributed applications
module server

gamnit :: server

Server-side network services for games and such
# Low-level write in MessagePack format to `Writer` streams
module write

import binary

redef class Writer

	# Write `null`, or nil, in MessagePack format
	fun write_msgpack_null do write_byte 0xC0

	# Write `bool` in MessagePack format
	fun write_msgpack_bool(bool: Bool)
	do write_byte(if bool then 0xC3 else 0xC2)

	# ---
	# Integers

	# Write the integer `value` either as the shortest possible MessagePack _int_
	fun write_msgpack_int(value: Int)
	do
		if value >= -0x20 and value <= 0x7F then
			write_msgpack_fixint value
		else if value >= 0 then
			if value <= 0xFF then
				write_msgpack_uint8 value
			else if value <= 0xFFFF then
				write_msgpack_uint16 value
			else if value <= 0xFFFF_FFFF then
				write_msgpack_uint32 value
			else #if value <= 0xFFFF_FFFF_FFFF_FFFF then
				write_msgpack_uint64 value
			end
		else if value >= -128 then
			write_msgpack_int8 value
		else if value >= -32768 then
			write_msgpack_int16 value
		else if value >= -2147483648 then
			write_msgpack_int32 value
		else
			write_msgpack_int64 value
		end
	end

	# Write `value` as a single byte with metadata
	#
	# Require: `value >= -0x20 and value <= 0x7F`
	fun write_msgpack_fixint(value: Int)
	do
		assert value >= -0x20 and value <= 0x7F
		write_byte value
	end

	# Write `value` over one unsigned byte, following 1 metadata byte
	#
	# Require: `value >= 0x00 and value <= 0xFF`
	fun write_msgpack_uint8(value: Int)
	do
		write_byte 0xCC
		write_bytes value.to_bytes(n_bytes=1)
	end

	# Write `value` over two unsigned bytes, following 1 metadata byte
	#
	# Require: `value >= 0x00 and value <= 0xFFFF`
	fun write_msgpack_uint16(value: Int)
	do
		write_byte 0xCD
		write_bytes value.to_bytes(n_bytes=2)
	end

	# Write `value` over 4 unsigned bytes, following 1 metadata byte
	#
	# Require: `value >= 0x00 and value <= 0xFFFF_FFFF`
	fun write_msgpack_uint32(value: Int)
	do
		write_byte 0xCE
		write_bytes value.to_bytes(n_bytes=4)
	end

	# Write `value` over 8 unsigned bytes, following 1 metadata byte
	#
	# Require: `value >= 0x00 and value <= 0xFFFF_FFFF_FFFF_FFFF`
	fun write_msgpack_uint64(value: Int)
	do
		write_byte 0xCF
		write_bytes value.to_bytes(n_bytes=8)
	end

	# Write `value` over one signed byte, following 1 metadata byte
	#
	# Require: `value >= -128  and value <= 127`
	fun write_msgpack_int8(value: Int)
	do
		write_byte 0xD0
		write_bytes value.to_bytes(n_bytes=1)
	end

	# Write `value` over two signed bytes, following 1 metadata byte
	fun write_msgpack_int16(value: Int)
	do
		write_byte 0xD1
		write_bytes value.to_bytes(n_bytes=2)
	end

	# Write `value` over 4 signed bytes, following 1 metadata byte
	fun write_msgpack_int32(value: Int)
	do
		write_byte 0xD2
		write_bytes value.to_bytes(n_bytes=4)
	end

	# Write `value` over 8 signed bytes, following 1 metadata byte
	fun write_msgpack_int64(value: Int)
	do
		write_byte 0xD3
		write_int64 value
	end

	# ---
	# Floats

	# Write `value` as a MessagePack float (losing precision)
	fun write_msgpack_float(value: Float)
	do
		write_byte 0xCA
		write_float value
	end

	# Write `value` as a MessagePack double
	fun write_msgpack_double(value: Float)
	do
		write_byte 0xCB
		write_double value
	end

	# ---
	# Strings

	# Write `text` in the shortest possible MessagePack format
	#
	# Require: `text.byte_length <= 0xFFFF_FFFF`
	fun write_msgpack_str(text: Text)
	do
		var len = text.byte_length
		if len <= 0x1F then
			write_msgpack_fixstr text
		else if len <= 0xFF then
			write_msgpack_str8 text
		else if len <= 0xFFFF then
			write_msgpack_str16 text
		else if len <= 0xFFFF_FFFF then
			write_msgpack_str32 text
		else
			abort
		end
	end

	# Write `text` in _fixstr_ format, max of 0x1F bytes
	#
	# Require: `text.byte_length <= 0x1F`
	fun write_msgpack_fixstr(text: Text)
	do
		var len = text.byte_length
		assert len <= 0x1F

		var b = 0b1010_0000 | len
		write_byte b

		write text
	end

	# Write `text` in _str8_ format, max of 0xFF bytes
	#
	# Require: `text.byte_length <= 0xFF`
	fun write_msgpack_str8(text: Text)
	do
		var len = text.byte_length
		assert len <= 0xFF

		write_byte 0xD9
		write_byte len
		write text
	end

	# Write `text` in _str16_ format, max of 0xFFFF bytes
	#
	# Require: `text.byte_length <= 0xFFFF`
	fun write_msgpack_str16(text: Text)
	do
		var len = text.byte_length
		assert len <= 0xFFFF

		write_byte 0xDA
		var len_bytes = len.to_bytes
		write_byte len_bytes[0]
		write_byte if len_bytes.length > 1 then len_bytes[1] else 0
		write text
	end

	# Write `text` in _str32_ format, max of 0xFFFF_FFFF bytes
	#
	# Require: `text.byte_length <= 0xFFFF_FFFF`
	fun write_msgpack_str32(text: Text)
	do
		var len = text.byte_length
		assert len <= 0xFFFF_FFFF

		write_byte 0xDB
		var len_bytes = len.to_bytes
		write_byte len_bytes[0]
		for i in [1..4[ do
			write_byte if len_bytes.length > i then len_bytes[i] else 0
		end
		write text
	end

	# ---
	# Binary data

	# Write `data` in the shortest possible MessagePack _bin_ format
	#
	# Require: `data.length <= 0xFFFF_FFFF`
	fun write_msgpack_bin(data: Bytes)
	do
		var len = data.length
		if len <= 0xFF then
			write_msgpack_bin8 data
		else if len <= 0xFFFF then
			write_msgpack_bin16 data
		else if len <= 0xFFFF_FFFF then
			write_msgpack_bin32 data
		else abort
	end

	# Write `data` in _bin8_ format, max of 0xFF bytes
	#
	# Require: `data.length <= 0xFF`
	fun write_msgpack_bin8(data: Bytes)
	do
		var len = data.length
		assert len <= 0xFF

		write_byte 0xC4
		write_byte len
		write_bytes data
	end

	# Write `data` in _bin16_ format, max of 0xFFFF bytes
	#
	# Require: `data.length <= 0xFFFF`
	fun write_msgpack_bin16(data: Bytes)
	do
		var len = data.length
		assert len <= 0xFFFF

		write_byte 0xC5
		write_bytes len.to_bytes(n_bytes=2)
		write_bytes data
	end

	# Write `data` in _bin32_ format, max of 0xFFFF_FFFF bytes
	#
	# Require: `data.length <= 0xFFFF_FFFF`
	fun write_msgpack_bin32(data: Bytes)
	do
		var len = data.length
		assert len <= 0xFFFF_FFFF

		write_byte 0xC6
		write_bytes len.to_bytes(n_bytes=4)
		write_bytes data
	end

	# ---
	# Arrays

	# Write an array header for `len` items in the shortest possible MessagePack _array_ format
	#
	# After writing the header, clients should write the array items.
	#
	# Require: `len <= 0xFFFF_FFFF`
	fun write_msgpack_array(len: Int)
	do
		if len <= 0x0F then
			write_msgpack_fixarray len
		else if len <= 0xFFFF then
			write_msgpack_array16 len
		else if len <= 0xFFFF_FFFF then
			write_msgpack_array32 len
		else
			abort
		end
	end

	# Write an array header for `len` items, max of 0x0F items
	#
	# After writing the header, clients should write the array items.
	#
	# Require: `len <= 0x0F`
	fun write_msgpack_fixarray(len: Int)
	do
		assert len <= 0x0F
		write_byte 0b1001_0000 | len
	end

	# Write an array header for `len` items, max of 0xFFFF items
	#
	# After writing the header, clients should write the array items.
	#
	# Require: `len <= 0xFFFF`
	fun write_msgpack_array16(len: Int)
	do
		assert len <= 0xFFFF
		write_byte 0xDC
		write_bytes len.to_bytes(n_bytes=2)
	end

	# Write an array header for `len` items, max of 0xFFFF_FFFF items
	#
	# After writing the header, clients should write the array items.
	#
	# Require: `len <= 0xFFFF_FFFF`
	fun write_msgpack_array32(len: Int)
	do
		assert len <= 0xFFFF_FFFF
		write_byte 0xDD
		write_bytes len.to_bytes(n_bytes=4)
	end

	# ---
	# Map

	# Write a map header for `len` keys/value pairs in the shortest possible MessagePack _map_ format
	#
	# After writing the header, clients should write the map data, alternating
	# between keys and values.
	#
	# Require: `len <= 0xFFFF_FFFF`
	fun write_msgpack_map(len: Int)
	do
		if len <= 0x0F then
			write_msgpack_fixmap len
		else if len <= 0xFFFF then
			write_msgpack_map16 len
		else if len <= 0xFFFF_FFFF then
			write_msgpack_map32 len
		else
			abort
		end
	end

	# Write a map header for `len` key/value pairs, max of 0x0F pairs
	#
	# After writing the header, clients should write the map data, alternating
	# between keys and values.
	#
	# Require: `len <= 0x0F`
	fun write_msgpack_fixmap(len: Int)
	do
		assert len <= 0x0F
		write_byte 0b1000_0000 | len
	end

	# Write a map header for `len` key/value pairs, max of 0xFFFF pairs
	#
	# After writing the header, clients should write the map data, alternating
	# between keys and values.
	#
	# Require: `len <= 0xFFFF`
	fun write_msgpack_map16(len: Int)
	do
		assert len <= 0xFFFF
		write_byte 0xDE
		write_bytes len.to_bytes(n_bytes=2)
	end

	# Write a map header for `len` key/value pairs, max of 0xFFFF_FFFF pairs
	#
	# After writing the header, clients should write the map data, alternating
	# between keys and values.
	#
	# Require: `len <= 0xFFFF_FFFF`
	fun write_msgpack_map32(len: Int)
	do
		assert len <= 0xFFFF_FFFF
		write_byte 0xDF
		write_bytes len.to_bytes(n_bytes=4)
	end

	# ---
	# Ext

	# Write an application-specific extension for `typ` and `bytes` in the shortest possible MessagePack _ext_ format
	#
	# Require: `bytes.length <= 0xFFFF_FFFF`
	#
	# ~~~
	# var writer = new BytesWriter
	# writer.write_msgpack_ext(0x0A, b"\x0B\x0C\x0D")
	# assert writer.bytes == b"\xC7\x03\x0A\x0B\x0C\x0D"
	# ~~~
	fun write_msgpack_ext(typ: Int, bytes: Bytes)
	do
		var len = bytes.length
		if len == 1 then
			write_msgpack_fixext1 typ
			write_byte bytes.first
		else if len == 2 then
			write_msgpack_fixext2 typ
			write_bytes bytes
		else if len == 4 then
			write_msgpack_fixext4 typ
			write_bytes bytes
		else if len == 8 then
			write_msgpack_fixext8 typ
			write_bytes bytes
		else if len == 16 then
			write_msgpack_fixext16 typ
			write_bytes bytes
		else if len <= 0xFF then
			write_msgpack_ext8(typ, len)
			write_bytes bytes
		else if len <= 0xFFFF then
			write_msgpack_ext16(typ, len)
			write_bytes bytes
		else if len <= 0xFFFF_FFFF then
			write_msgpack_ext32(typ, len)
			write_bytes bytes
		else
			abort
		end
	end

	# Write the header for an application-specific extension of one data byte
	#
	# After writing the header, clients should write the data byte.
	fun write_msgpack_fixext1(typ: Int)
	do
		write_byte 0xD4
		write_byte typ
	end

	# Write the header for an application-specific extension of two data bytes
	#
	# After writing the header, clients should write the two data bytes.
	fun write_msgpack_fixext2(typ: Int)
	do
		write_byte 0xD5
		write_byte typ
	end

	# Write the header for an application-specific extension of 4 data bytes
	#
	# After writing the header, clients should write the 4 data bytes.
	fun write_msgpack_fixext4(typ: Int)
	do
		write_byte 0xD6
		write_byte typ
	end

	# Write the header for an application-specific extension of 8 data bytes
	#
	# After writing the header, clients should write the 8 data bytes.
	fun write_msgpack_fixext8(typ: Int)
	do
		write_byte 0xD7
		write_byte typ
	end

	# Write the header for an application-specific extension of 16 data bytes
	#
	# After writing the header, clients should write the 16 data bytes.
	fun write_msgpack_fixext16(typ: Int)
	do
		write_byte 0xD8
		write_byte typ
	end

	# Write the header for an application-specific extension of `len` data bytes
	#
	# After writing the header, clients should write the data bytes.
	#
	# Require: `len >= 0 and <= 0xFF`
	fun write_msgpack_ext8(typ, len: Int)
	do
		assert len >= 0 and len <= 0xFF
		write_byte 0xC7
		write_byte len
		write_byte typ
	end

	# Write the header for an application-specific extension of `len` data bytes
	#
	# After writing the header, clients should write the data bytes.
	#
	# Require: `len >= 0 and <= 0xFFFF`
	fun write_msgpack_ext16(typ, len: Int)
	do
		assert len >= 0 and len <= 0xFFFF
		write_byte 0xC8
		write_bytes len.to_bytes(n_bytes=2)
		write_byte typ
	end

	# Write the header for an application-specific extension of `len` data bytes
	#
	# After writing the header, clients should write the data bytes.
	#
	# Require: `len >= 0 and <= 0xFFFF_FFFF`
	fun write_msgpack_ext32(typ, len: Int)
	do
		assert len >= 0 and len <= 0xFFFF_FFFF
		write_byte 0xC9
		write_bytes len.to_bytes(n_bytes=4)
		write_byte typ
	end

	# TODO timestamps
end
lib/msgpack/write.nit:15,1--533,3