Skip to content

Commit

Permalink
Lint
Browse files Browse the repository at this point in the history
  • Loading branch information
samuelmanzanera committed Oct 17, 2023
1 parent f4a050a commit 25a23b6
Show file tree
Hide file tree
Showing 3 changed files with 36 additions and 47 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -8,47 +8,29 @@ defmodule Archethic.TransactionChain.TransactionData.Recipient.ArgumentsEncoding

@spec serialize(args :: list(TypedEncoding.arg()), mode :: Transaction.serialization_mode()) ::
bitstring()
def serialize(args, mode) when is_list(args) and mode in [:compact, :extended] do
bit_size =
case mode do
:compact ->
1

:extended ->
8
end

def serialize(args, mode) do
bin =
args
|> Enum.map(&TypedEncoding.serialize(&1, bit_size))
|> Enum.map(&TypedEncoding.serialize(&1, mode))
|> :erlang.list_to_bitstring()

<<length(args)::8, bin::bitstring>>
end

@spec deserialize(binary :: bitstring(), mode :: Transaction.serialization_mode()) ::
{list(TypedEncoding.arg()), bitstring()}
def deserialize(<<nb_args::8, rest::bitstring>>, mode) when mode in [:compact, :extended] do
bit_size =
case mode do
:compact ->
1

:extended ->
8
end

do_deserialize(rest, nb_args, [], bit_size)
def deserialize(<<nb_args::8, rest::bitstring>>, mode) do
do_deserialize(rest, nb_args, [], mode)
end

defp do_deserialize(<<>>, _nb_args, acc, _bit_size), do: {Enum.reverse(acc), <<>>}
defp do_deserialize(<<>>, _nb_args, acc, _mode), do: {Enum.reverse(acc), <<>>}

defp do_deserialize(rest, nb_args, acc, _bit_size) when length(acc) == nb_args do
defp do_deserialize(rest, nb_args, acc, _mode) when length(acc) == nb_args do
{Enum.reverse(acc), rest}
end

defp do_deserialize(binary, nb_args, acc, bit_size) do
{arg, rest} = TypedEncoding.deserialize(binary, bit_size)
do_deserialize(rest, nb_args, [arg | acc], bit_size)
defp do_deserialize(binary, nb_args, acc, mode) do
{arg, rest} = TypedEncoding.deserialize(binary, mode)
do_deserialize(rest, nb_args, [arg | acc], mode)
end
end
39 changes: 23 additions & 16 deletions lib/archethic/utils/typed_encoding.ex
Original file line number Diff line number Diff line change
Expand Up @@ -15,9 +15,13 @@ defmodule Archethic.Utils.TypedEncoding do

alias Archethic.Utils
alias Archethic.Utils.VarInt
alias Archethic.TransactionChain.Transaction

@spec serialize(arg(), bit_size :: pos_integer()) :: bitstring()
def serialize(int, bit_size) when is_integer(int) do
@spec serialize(arg(), mode :: Transaction.serialization_mode()) :: bitstring()
def serialize(data, :compact), do: do_serialize(data, 1)
def serialize(data, :extended), do: do_serialize(data, 8)

defp do_serialize(int, bit_size) when is_integer(int) do
sign_bit = sign_to_bit(int)

bin =
Expand All @@ -28,7 +32,7 @@ defmodule Archethic.Utils.TypedEncoding do
<<@type_int::8, sign_bit::integer-size(bit_size), bin::bitstring>>
end

def serialize(float, bit_size) when is_float(float) do
defp do_serialize(float, bit_size) when is_float(float) do
sign_bit = sign_to_bit(float)

bin =
Expand All @@ -40,13 +44,13 @@ defmodule Archethic.Utils.TypedEncoding do
<<@type_float::8, sign_bit::integer-size(bit_size), bin::bitstring>>
end

def serialize(bin, _bit_size) when is_binary(bin) do
defp do_serialize(bin, _bit_size) when is_binary(bin) do
size = byte_size(bin)
size_bin = VarInt.from_value(size)
<<@type_str::8, size_bin::binary, bin::bitstring>>
end

def serialize(list, bit_size) when is_list(list) do
defp do_serialize(list, bit_size) when is_list(list) do
size = length(list)
size_bin = VarInt.from_value(size)

Expand All @@ -55,7 +59,7 @@ defmodule Archethic.Utils.TypedEncoding do
end)
end

def serialize(map, bit_size) when is_map(map) do
defp do_serialize(map, bit_size) when is_map(map) do
size = map_size(map)
size_bin = VarInt.from_value(size)

Expand All @@ -64,41 +68,44 @@ defmodule Archethic.Utils.TypedEncoding do
end)
end

def serialize(bool, bit_size) when is_boolean(bool) do
defp do_serialize(bool, bit_size) when is_boolean(bool) do
bool_bit = if bool, do: 1, else: 0
<<@type_bool::8, bool_bit::integer-size(bit_size)>>
end

def serialize(nil, _bit_size) do
defp do_serialize(nil, _bit_size) do
<<@type_nil::8>>
end

defp sign_to_bit(num) when num >= 0, do: 1
defp sign_to_bit(_num), do: 0

@spec deserialize(binary :: bitstring(), bit_size :: pos_integer()) ::
@spec deserialize(binary :: bitstring(), mode :: Transaction.serialization_mode()) ::
{list(arg()), bitstring()}
def deserialize(<<@type_int::8, rest::bitstring>>, bit_size) do
def deserialize(bin, :compact), do: do_deserialize(bin, 1)
def deserialize(bin, :extended), do: do_deserialize(bin, 8)

defp do_deserialize(<<@type_int::8, rest::bitstring>>, bit_size) do
<<sign_bit::integer-size(bit_size), rest::bitstring>> = rest
{int, rest} = VarInt.get_value(rest)
int = int * bit_to_sign(sign_bit)
{int, rest}
end

def deserialize(<<@type_float::8, rest::bitstring>>, bit_size) do
defp do_deserialize(<<@type_float::8, rest::bitstring>>, bit_size) do
<<sign_bit::integer-size(bit_size), rest::bitstring>> = rest
{int, rest} = VarInt.get_value(rest)
float = Utils.from_bigint(int) * bit_to_sign(sign_bit)
{float, rest}
end

def deserialize(<<@type_str::8, rest::bitstring>>, _bit_size) do
defp do_deserialize(<<@type_str::8, rest::bitstring>>, _bit_size) do
{size, rest} = VarInt.get_value(rest)
<<bin::binary-size(size), rest::bitstring>> = rest
{bin, rest}
end

def deserialize(<<@type_list::8, rest::bitstring>>, bit_size) do
defp do_deserialize(<<@type_list::8, rest::bitstring>>, bit_size) do
{size, rest} = VarInt.get_value(rest)

case size do
Expand All @@ -117,7 +124,7 @@ defmodule Archethic.Utils.TypedEncoding do
end
end

def deserialize(<<@type_map::8, rest::bitstring>>, bit_size) do
defp do_deserialize(<<@type_map::8, rest::bitstring>>, bit_size) do
{size, rest} = VarInt.get_value(rest)

case size do
Expand All @@ -134,13 +141,13 @@ defmodule Archethic.Utils.TypedEncoding do
end
end

def deserialize(<<@type_bool::8, rest::bitstring>>, bit_size) do
defp do_deserialize(<<@type_bool::8, rest::bitstring>>, bit_size) do
<<bool_bit::integer-size(bit_size), rest::bitstring>> = rest
bool = bool_bit == 1
{bool, rest}
end

def deserialize(<<@type_nil::8, rest::bitstring>>, _bit_size), do: {nil, rest}
defp do_deserialize(<<@type_nil::8, rest::bitstring>>, _bit_size), do: {nil, rest}

defp bit_to_sign(0), do: -1
defp bit_to_sign(1), do: 1
Expand Down
8 changes: 4 additions & 4 deletions test/archethic/utils/typed_encoding_test.exs
Original file line number Diff line number Diff line change
Expand Up @@ -20,13 +20,13 @@ defmodule Archethic.Utils.TypedEncodingTest do
) do
assert {^data, ""} =
data
|> TypedEncoding.serialize(8)
|> TypedEncoding.deserialize(8)
|> TypedEncoding.serialize(:extended)
|> TypedEncoding.deserialize(:extended)

assert {^data, ""} =
data
|> TypedEncoding.serialize(1)
|> TypedEncoding.deserialize(1)
|> TypedEncoding.serialize(:compact)
|> TypedEncoding.deserialize(:compact)
end
end

Expand Down

0 comments on commit 25a23b6

Please sign in to comment.