Current section
Files
Jump to
Current section
Files
src/gleeth@encoding@rlp.erl
-module(gleeth@encoding@rlp).
-compile([no_auto_import, nowarn_unused_vars, nowarn_unused_function, nowarn_nomatch, inline]).
-define(FILEPATH, "src/gleeth/encoding/rlp.gleam").
-export([encode_string/1, encode_int/1, encode_hex_field/1, decode/1, encode/1]).
-export_type([rlp_item/0, rlp_error/0]).
-if(?OTP_RELEASE >= 27).
-define(MODULEDOC(Str), -moduledoc(Str)).
-define(DOC(Str), -doc(Str)).
-else.
-define(MODULEDOC(Str), -compile([])).
-define(DOC(Str), -compile([])).
-endif.
-type rlp_item() :: {rlp_bytes, bitstring()} | {rlp_list, list(rlp_item())}.
-type rlp_error() :: {invalid_prefix, integer()} |
unexpected_end |
extra_data |
invalid_length.
-file("src/gleeth/encoding/rlp.gleam", 186).
?DOC(" Convert a UTF-8 string to an RLP item\n").
-spec encode_string(binary()) -> rlp_item().
encode_string(Value) ->
{rlp_bytes, gleam_stdlib:identity(Value)}.
-file("src/gleeth/encoding/rlp.gleam", 221).
-spec do_to_binary_be(integer(), bitstring()) -> bitstring().
do_to_binary_be(Value, Acc) ->
case Value of
0 ->
Acc;
_ ->
Byte = erlang:'band'(Value, 16#ff),
Rest = erlang:'bsr'(Value, 8),
do_to_binary_be(Rest, <<Byte:8, Acc/bitstring>>)
end.
-file("src/gleeth/encoding/rlp.gleam", 214).
?DOC(" Convert a non-negative integer to minimal big-endian bytes\n").
-spec to_binary_be(integer()) -> bitstring().
to_binary_be(Value) ->
case Value of
0 ->
<<>>;
_ ->
do_to_binary_be(Value, <<>>)
end.
-file("src/gleeth/encoding/rlp.gleam", 67).
-spec encode_length(integer(), integer()) -> bitstring().
encode_length(Len, Offset) ->
case Len =< 55 of
true ->
Prefix_byte = Offset + Len,
<<Prefix_byte:8>>;
false ->
Len_bytes = to_binary_be(Len),
Len_of_len = erlang:byte_size(Len_bytes),
Prefix_byte@1 = (Offset + 55) + Len_of_len,
<<Prefix_byte@1:8, Len_bytes/bitstring>>
end.
-file("src/gleeth/encoding/rlp.gleam", 35).
-spec encode_bytes(bitstring()) -> bitstring().
encode_bytes(Data) ->
case Data of
<<Byte:8>> ->
case Byte < 16#80 of
true ->
Data;
false ->
Prefix = encode_length(1, 16#80),
<<Prefix/bitstring, Data/bitstring>>
end;
_ ->
Len = erlang:byte_size(Data),
Prefix@1 = encode_length(Len, 16#80),
<<Prefix@1/bitstring, Data/bitstring>>
end.
-file("src/gleeth/encoding/rlp.gleam", 178).
?DOC(
" Convert an integer to an RLP item.\n"
" Uses big-endian minimal encoding: 0 becomes empty bytes.\n"
).
-spec encode_int(integer()) -> rlp_item().
encode_int(Value) ->
case Value of
0 ->
{rlp_bytes, <<>>};
_ ->
{rlp_bytes, to_binary_be(Value)}
end.
-file("src/gleeth/encoding/rlp.gleam", 237).
-spec do_bytes_to_int(bitstring(), integer()) -> integer().
do_bytes_to_int(Data, Acc) ->
case Data of
<<Byte:8, Rest/bitstring>> ->
do_bytes_to_int(Rest, (Acc * 256) + Byte);
_ ->
Acc
end.
-file("src/gleeth/encoding/rlp.gleam", 233).
?DOC(" Convert big-endian bytes to an integer\n").
-spec bytes_to_int(bitstring()) -> integer().
bytes_to_int(Data) ->
do_bytes_to_int(Data, 0).
-file("src/gleeth/encoding/rlp.gleam", 245).
?DOC(" Take n bytes from the front of a BitArray\n").
-spec take_bytes(bitstring(), integer()) -> {ok, {bitstring(), bitstring()}} |
{error, rlp_error()}.
take_bytes(Data, N) ->
case N =:= 0 of
true ->
{ok, {<<>>, Data}};
false ->
Available = erlang:byte_size(Data),
case Available >= N of
true ->
Taken@1 = case gleam_stdlib:bit_array_slice(Data, 0, N) of
{ok, Taken} -> Taken;
_assert_fail ->
erlang:error(#{gleam_error => let_assert,
message => <<"Pattern match failed, no pattern matched the value."/utf8>>,
file => <<?FILEPATH/utf8>>,
module => <<"gleeth/encoding/rlp"/utf8>>,
function => <<"take_bytes"/utf8>>,
line => 252,
value => _assert_fail,
start => 7217,
'end' => 7267,
pattern_start => 7228,
pattern_end => 7237})
end,
Rest@1 = case gleam_stdlib:bit_array_slice(
Data,
N,
Available - N
) of
{ok, Rest} -> Rest;
_assert_fail@1 ->
erlang:error(#{gleam_error => let_assert,
message => <<"Pattern match failed, no pattern matched the value."/utf8>>,
file => <<?FILEPATH/utf8>>,
module => <<"gleeth/encoding/rlp"/utf8>>,
function => <<"take_bytes"/utf8>>,
line => 253,
value => _assert_fail@1,
start => 7278,
'end' => 7339,
pattern_start => 7289,
pattern_end => 7297})
end,
{ok, {Taken@1, Rest@1}};
false ->
{error, unexpected_end}
end
end.
-file("src/gleeth/encoding/rlp.gleam", 263).
?DOC(" Strip leading zero bytes from a BitArray\n").
-spec strip_leading_zeros(bitstring()) -> bitstring().
strip_leading_zeros(Data) ->
case Data of
<<0:8, Rest/bitstring>> ->
strip_leading_zeros(Rest);
_ ->
Data
end.
-file("src/gleeth/encoding/rlp.gleam", 192).
?DOC(
" Convert a \"0x...\" hex string to an RLP item with minimal encoding.\n"
" Strips the 0x prefix, decodes hex to bytes, and removes leading zero bytes.\n"
).
-spec encode_hex_field(binary()) -> rlp_item().
encode_hex_field(Hex_string) ->
Stripped = gleeth@utils@hex:strip_prefix(Hex_string),
case Stripped of
<<""/utf8>> ->
{rlp_bytes, <<>>};
_ ->
Padded = case string:length(Stripped) rem 2 of
0 ->
Stripped;
_ ->
<<"0"/utf8, Stripped/binary>>
end,
case gleeth@utils@hex:decode(Padded) of
{ok, Bytes} ->
{rlp_bytes, strip_leading_zeros(Bytes)};
{error, _} ->
{rlp_bytes, <<>>}
end
end.
-file("src/gleeth/encoding/rlp.gleam", 161).
-spec decode_list_payload(bitstring()) -> {ok, list(rlp_item())} |
{error, rlp_error()}.
decode_list_payload(Data) ->
case erlang:byte_size(Data) of
0 ->
{ok, []};
_ ->
gleam@result:'try'(
decode_item(Data),
fun(_use0) ->
{Item, Rest} = _use0,
gleam@result:'try'(
decode_list_payload(Rest),
fun(Items) -> {ok, [Item | Items]} end
)
end
)
end.
-file("src/gleeth/encoding/rlp.gleam", 95).
-spec decode_item(bitstring()) -> {ok, {rlp_item(), bitstring()}} |
{error, rlp_error()}.
decode_item(Data) ->
case Data of
<<>> ->
{error, unexpected_end};
<<Prefix:8, Rest/bitstring>> ->
decode_with_prefix(Prefix, Rest);
_ ->
{error, unexpected_end}
end.
-file("src/gleeth/encoding/rlp.gleam", 103).
-spec decode_with_prefix(integer(), bitstring()) -> {ok,
{rlp_item(), bitstring()}} |
{error, rlp_error()}.
decode_with_prefix(Prefix, Rest) ->
case Prefix < 16#80 of
true ->
{ok, {{rlp_bytes, <<Prefix:8>>}, Rest}};
false ->
case Prefix < 16#b8 of
true ->
Len = Prefix - 16#80,
gleam@result:'try'(
take_bytes(Rest, Len),
fun(_use0) ->
{Bytes, Remaining} = _use0,
{ok, {{rlp_bytes, Bytes}, Remaining}}
end
);
false ->
case Prefix < 16#c0 of
true ->
Len_of_len = Prefix - 16#b7,
gleam@result:'try'(
take_bytes(Rest, Len_of_len),
fun(_use0@1) ->
{Len_bytes, After_len} = _use0@1,
Len@1 = bytes_to_int(Len_bytes),
gleam@result:'try'(
take_bytes(After_len, Len@1),
fun(_use0@2) ->
{Bytes@1, Remaining@1} = _use0@2,
{ok,
{{rlp_bytes, Bytes@1},
Remaining@1}}
end
)
end
);
false ->
case Prefix < 16#f8 of
true ->
Len@2 = Prefix - 16#c0,
gleam@result:'try'(
take_bytes(Rest, Len@2),
fun(_use0@3) ->
{Payload, Remaining@2} = _use0@3,
gleam@result:'try'(
decode_list_payload(Payload),
fun(Items) ->
{ok,
{{rlp_list, Items},
Remaining@2}}
end
)
end
);
false ->
Len_of_len@1 = Prefix - 16#f7,
gleam@result:'try'(
take_bytes(Rest, Len_of_len@1),
fun(_use0@4) ->
{Len_bytes@1, After_len@1} = _use0@4,
Len@3 = bytes_to_int(Len_bytes@1),
gleam@result:'try'(
take_bytes(After_len@1, Len@3),
fun(_use0@5) ->
{Payload@1, Remaining@3} = _use0@5,
gleam@result:'try'(
decode_list_payload(
Payload@1
),
fun(Items@1) ->
{ok,
{{rlp_list,
Items@1},
Remaining@3}}
end
)
end
)
end
)
end
end
end
end.
-file("src/gleeth/encoding/rlp.gleam", 87).
?DOC(" Decode bytes into an RLP item\n").
-spec decode(bitstring()) -> {ok, rlp_item()} | {error, rlp_error()}.
decode(Data) ->
gleam@result:'try'(
decode_item(Data),
fun(_use0) ->
{Item, Rest} = _use0,
case erlang:byte_size(Rest) of
0 ->
{ok, Item};
_ ->
{error, extra_data}
end
end
).
-file("src/gleeth/encoding/rlp.gleam", 56).
-spec encode_list(list(rlp_item())) -> bitstring().
encode_list(Items) ->
Payload = gleam@list:fold(
Items,
<<>>,
fun(Acc, Item) ->
Encoded = encode(Item),
<<Acc/bitstring, Encoded/bitstring>>
end
),
Len = erlang:byte_size(Payload),
Prefix = encode_length(Len, 16#c0),
<<Prefix/bitstring, Payload/bitstring>>.
-file("src/gleeth/encoding/rlp.gleam", 28).
?DOC(" Encode an RLP item to bytes\n").
-spec encode(rlp_item()) -> bitstring().
encode(Item) ->
case Item of
{rlp_bytes, Data} ->
encode_bytes(Data);
{rlp_list, Items} ->
encode_list(Items)
end.