defmodule Bolt.Sips.Internals.PackStream.V1 do defmacro __using__(_options) do quote do import unquote(__MODULE__) @last_version Bolt.Sips.Internals.BoltVersionHelper.last() @int8 -128..-17 @int16_low -32_768..-129 @int16_high 128..32_767 @int32_low -2_147_483_648..-32_769 @int32_high 32_768..2_147_483_647 @int64_low -9_223_372_036_854_775_808..-2_147_483_649 @int64_high 2_147_483_648..9_223_372_036_854_775_807 # Null @null_marker 0xC0 # Boolean @true_marker 0xC3 @false_marker 0xC2 # String @tiny_bitstring_marker 0x8 @bitstring8_marker 0xD0 @bitstring16_marker 0xD1 @bitstring32_marker 0xD2 # Integer @int8_marker 0xC8 @int16_marker 0xC9 @int32_marker 0xCA @int64_marker 0xCB # Float @float_marker 0xC1 # List @tiny_list_marker 0x9 @list8_marker 0xD4 @list16_marker 0xD5 @list32_marker 0xD6 # Map @tiny_map_marker 0xA @map8_marker 0xD8 @map16_marker 0xD9 @map32_marker 0xDA # Structure @tiny_struct_marker 0xB @struct8_marker 0xDC @struct16_marker 0xDD @spec do_call_encode(atom(), any(), integer()) :: binary() | PackStreamError.t() # Atoms defp do_call_encode(:atom, nil, bolt_version) when bolt_version <= @last_version do <<@null_marker>> end defp do_call_encode(:atom, true, bolt_version) when bolt_version <= @last_version do <<@true_marker>> end defp do_call_encode(:atom, false, bolt_version) when bolt_version <= @last_version do <<@false_marker>> end defp do_call_encode(:atom, other, bolt_version) when bolt_version <= @last_version do call_encode(:string, other |> Atom.to_string(), bolt_version) end # Strings defp do_call_encode(:string, string, bolt_version) when bolt_version <= @last_version and byte_size(string) <= 15 do [<<@tiny_bitstring_marker::4, byte_size(string)::4>>, string] end defp do_call_encode(:string, string, bolt_version) when bolt_version <= @last_version and byte_size(string) <= 255 do [<<@bitstring8_marker, byte_size(string)::8>>, string] end defp do_call_encode(:string, string, bolt_version) when bolt_version <= @last_version and byte_size(string) <= 65_535 do [<<@bitstring16_marker, byte_size(string)::16>>, string] end defp do_call_encode(:string, string, bolt_version) when bolt_version <= @last_version and byte_size(string) <= 4_294_967_295 do [<<@bitstring32_marker, byte_size(string)::32>>, string] end # Integer defp do_call_encode(:integer, integer, bolt_version) when bolt_version <= @last_version and integer in -16..127 do <> end defp do_call_encode(:integer, integer, bolt_version) when bolt_version <= @last_version and integer in @int8 do <<@int8_marker, integer>> end defp do_call_encode(:integer, integer, bolt_version) when bolt_version <= @last_version and integer in @int16_low when bolt_version <= @last_version and integer in @int16_high do <<@int16_marker, integer::16>> end defp do_call_encode(:integer, integer, bolt_version) when bolt_version <= @last_version and integer in @int32_low when bolt_version <= @last_version and integer in @int32_high do <<@int32_marker, integer::32>> end defp do_call_encode(:integer, integer, bolt_version) when bolt_version <= @last_version and integer in @int64_low when bolt_version <= @last_version and integer in @int64_high do <<@int64_marker, integer::64>> end # Float defp do_call_encode(:float, number, bolt_version) when bolt_version <= 3 do <<@float_marker, number::float>> end # lists defp do_call_encode(:list, list, bolt_version) when bolt_version <= @last_version and length(list) <= 15 do [<<@tiny_list_marker::4, length(list)::4>>, encode_list_data(list, bolt_version)] end defp do_call_encode(:list, list, bolt_version) when bolt_version <= @last_version and length(list) <= 255 do [<<@list8_marker, length(list)::8>>, encode_list_data(list, bolt_version)] end defp do_call_encode(:list, list, bolt_version) when bolt_version <= @last_version and length(list) <= 65_535 do [<<@list16_marker, length(list)::16>>, encode_list_data(list, bolt_version)] end defp do_call_encode(:list, list, bolt_version) when bolt_version <= @last_version and length(list) <= 4_294_967_295 do [<<@list32_marker, length(list)::32>>, encode_list_data(list, bolt_version)] end # maps defp do_call_encode(:map, map, bolt_version) when bolt_version <= @last_version and map_size(map) <= 15 do [<<@tiny_map_marker::4, map_size(map)::4>>, encode_kv(map, bolt_version)] end defp do_call_encode(:map, map, bolt_version) when bolt_version <= @last_version and map_size(map) <= 255 do [<<@map8_marker, map_size(map)::8>>, encode_kv(map, bolt_version)] end defp do_call_encode(:map, map, bolt_version) when bolt_version <= @last_version and map_size(map) <= 65_535 do [<<@map16_marker, map_size(map)::16>>, encode_kv(map, bolt_version)] end defp do_call_encode(:map, map, bolt_version) when bolt_version <= @last_version and map_size(map) <= 4_294_967_295 do [<<@map32_marker, map_size(map)::32>>, encode_kv(map, bolt_version)] end # Structs defp do_call_encode(:struct, {signature, list}, bolt_version) when bolt_version <= @last_version and length(list) <= 15 do [ <<@tiny_struct_marker::4, length(list)::4, signature>>, encode_list_data(list, bolt_version) ] end defp do_call_encode(:struct, {signature, list}, bolt_version) when bolt_version <= @last_version and length(list) <= 255 do [<<@struct8_marker::8, length(list)::8, signature>>, encode_list_data(list, bolt_version)] end defp do_call_encode(:struct, {signature, list}, bolt_version) when bolt_version <= @last_version and length(list) <= 65_535 do [ <<@struct16_marker::8, length(list)::16, signature>>, encode_list_data(list, bolt_version) ] end end end end