Current section
Files
Jump to
Current section
Files
src/packet.erl
-module(packet).
-compile([no_auto_import, nowarn_unused_vars, nowarn_unused_function, nowarn_nomatch]).
-export([packet_type_to_int/1, to_bytes/1, min_packet_size_bytes/0, max_packet_size_bytes/0, new/3, from_bytes/1]).
-export_type([packet/0, packet_type/0]).
-type packet() :: {packet, integer(), integer(), integer(), bitstring()}.
-type packet_type() :: server_data_auth |
server_data_auth_response |
server_data_exec_command |
server_data_response_value.
-spec packet_type_to_int(packet_type()) -> integer().
packet_type_to_int(Pt) ->
case Pt of
server_data_auth ->
3;
server_data_auth_response ->
2;
server_data_exec_command ->
2;
server_data_response_value ->
0
end.
-spec to_bytes(packet()) -> bitstring().
to_bytes(Packet) ->
_pipe = gleam@bytes_builder:new(),
_pipe@1 = gleam@bytes_builder:append(
_pipe,
<<(erlang:element(2, Packet)):32/integer-little>>
),
_pipe@2 = gleam@bytes_builder:append(
_pipe@1,
<<(erlang:element(3, Packet)):32/integer-little>>
),
_pipe@3 = gleam@bytes_builder:append(
_pipe@2,
<<(erlang:element(4, Packet)):32/integer-little>>
),
_pipe@4 = gleam@bytes_builder:append(_pipe@3, erlang:element(5, Packet)),
_pipe@5 = gleam@bytes_builder:append(_pipe@4, <<16#00, 16#00>>),
erlang:list_to_bitstring(_pipe@5).
-spec min_packet_size_bytes() -> integer().
min_packet_size_bytes() ->
2 + 8.
-spec max_packet_size_bytes() -> integer().
max_packet_size_bytes() ->
4096 + min_packet_size_bytes().
-spec new(packet_type(), integer(), binary()) -> {ok, packet()} |
{error, errors:error()}.
new(Packet_type, Packet_id, Body) ->
Body_size = erlang:byte_size(Body),
Size = (Body_size + 8) + 2,
Max = max_packet_size_bytes(),
case Size of
_ when Size > Max ->
{error, {body_too_large, Body_size}};
_ ->
Bytes = begin
_pipe = Body,
_pipe@1 = gleam_stdlib:wrap_list(_pipe),
erlang:list_to_bitstring(_pipe@1)
end,
{ok,
{packet,
Size,
Packet_id,
packet_type_to_int(Packet_type),
Bytes}}
end.
-spec from_bytes(bitstring()) -> {ok, packet()} | {error, errors:error()}.
from_bytes(Bytes) ->
Min_ps = min_packet_size_bytes(),
case Bytes of
<<Size:32/little-integer, Rest/bitstring>> ->
case Size of
_ when Size < Min_ps ->
{error, {packet_size_too_small, Bytes, Size}};
_ ->
Body_size_bits = ((Size - 8) - 2) * 8,
case Rest of
<<Id:32/integer-little,
Typ:32/integer-little,
Body:Body_size_bits/bitstring,
0,
0>> ->
case Typ of
3 ->
{ok, {packet, Size, Id, Typ, Body}};
2 ->
{ok, {packet, Size, Id, Typ, Body}};
0 ->
{ok, {packet, Size, Id, Typ, Body}};
_ ->
{error, {invalid_packet_type, Bytes, Typ}}
end;
_ ->
{error, {invalid_packet_structure, Bytes}}
end
end;
_ ->
{error, {invalid_packet_structure, Bytes}}
end.