Packages

A Gleam FTP/FTPS client library with full RFC support for both passive and active mode

Current section

Files

Jump to
gftp src gftp@stream.erl
Raw

src/gftp@stream.erl

-module(gftp@stream).
-compile([no_auto_import, nowarn_unused_vars, nowarn_unused_function, nowarn_nomatch, inline]).
-define(FILEPATH, "src/gftp/stream.gleam").
-export(['receive'/2, receive_exact/3, send/2, upgrade_to_ssl/2, downgrade_to_tcp/1, local_address/1, peer_address/1, set_line_mode/1, set_raw_mode/1, shutdown/1]).
-export_type([data_stream/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.
?MODULEDOC(
" The stream module provides an interface for working with a network stream, which can either be a TCP stream or a TLS stream.\n"
" It abstracts away the differences between the two types of streams and provides a unified interface for reading and writing data.\n"
).
-type data_stream() :: {ssl, kafein:ssl_socket(), mug:socket()} |
{tcp, mug:socket()}.
-file("src/gftp/stream.gleam", 45).
?DOC(
" Receive a message from the peer.\n"
"\n"
" Errors if the socket is closed, if the timeout is reached, or if any other error occurs during the receive operation.\n"
" The error is returned as a [`mug.Error`]. In case of success, it returns the received data as a `BitArray`.\n"
).
-spec 'receive'(data_stream(), integer()) -> {ok, bitstring()} |
{error, mug:error()}.
'receive'(Stream, Timeout) ->
case Stream of
{ssl, Ssl_socket, _} ->
kafein:'receive'(Ssl_socket, Timeout);
{tcp, Tcp_socket} ->
mug:'receive'(Tcp_socket, Timeout)
end.
-file("src/gftp/stream.gleam", 56).
?DOC(
" Receive an exact number of bytes from the peer.\n"
"\n"
" Errors if the socket is closed, if the timeout is reached, or if any other error occurs during the receive operation.\n"
" The error is returned as a [`mug.Error`]. In case of success, it returns the received data as a `BitArray`.\n"
).
-spec receive_exact(data_stream(), integer(), integer()) -> {ok, bitstring()} |
{error, mug:error()}.
receive_exact(Stream, Size, Timeout) ->
case Stream of
{ssl, Ssl_socket, _} ->
kafein:receive_exact(Ssl_socket, Size, Timeout);
{tcp, Tcp_socket} ->
mug:receive_exact(Tcp_socket, Size, Timeout)
end.
-file("src/gftp/stream.gleam", 71).
?DOC(
" Sends data over the provided stream.\n"
" It handles both SSL and TCP streams, abstracting away the differences between them.\n"
"\n"
" Returns a Result indicating success (`Nil`) or an error ([`mug.Error`]) if the send operation fails.\n"
).
-spec send(data_stream(), bitstring()) -> {ok, nil} | {error, mug:error()}.
send(Stream, Data) ->
case Stream of
{ssl, Ssl_socket, _} ->
kafein:send(Ssl_socket, Data);
{tcp, Tcp_socket} ->
mug:send(Tcp_socket, Data)
end.
-file("src/gftp/stream.gleam", 79).
?DOC(" Upgrades a TCP stream to an SSL stream using the provided options. If the stream is already an SSL stream, it returns it as is.\n").
-spec upgrade_to_ssl(data_stream(), kafein:wrap_options()) -> {ok,
data_stream()} |
{error, kafein:error()}.
upgrade_to_ssl(Stream, Options) ->
case Stream of
{ssl, _, _} ->
{ok, Stream};
{tcp, Tcp_socket} ->
case kafein:wrap(stream_ffi:patch_wrap_options(Options), Tcp_socket) of
{ok, Ssl_socket} ->
{ok, {ssl, Ssl_socket, Tcp_socket}};
{error, E} ->
{error, E}
end
end.
-file("src/gftp/stream.gleam", 95).
?DOC(" Downgrades an SSL stream to a TCP stream. If the stream is already a TCP stream, it returns it as is.\n").
-spec downgrade_to_tcp(data_stream()) -> data_stream().
downgrade_to_tcp(Stream) ->
case Stream of
{ssl, _, Tcp_socket} ->
{tcp, Tcp_socket};
{tcp, _} ->
Stream
end.
-file("src/gftp/stream.gleam", 103).
?DOC(" Retrieves the local address (IP and port) of the underlying TCP socket.\n").
-spec local_address(data_stream()) -> {ok, {binary(), integer()}} |
{error, mug:error()}.
local_address(Stream) ->
case Stream of
{ssl, _, Tcp_socket} ->
stream_ffi:local_address(Tcp_socket);
{tcp, Tcp_socket@1} ->
stream_ffi:local_address(Tcp_socket@1)
end.
-file("src/gftp/stream.gleam", 111).
?DOC(" Retrieves the peer address (IP and port) of the underlying TCP socket.\n").
-spec peer_address(data_stream()) -> {ok, {binary(), integer()}} |
{error, mug:error()}.
peer_address(Stream) ->
case Stream of
{ssl, _, Tcp_socket} ->
stream_ffi:peer_address(Tcp_socket);
{tcp, Tcp_socket@1} ->
stream_ffi:peer_address(Tcp_socket@1)
end.
-file("src/gftp/stream.gleam", 120).
?DOC(
" Set the socket to line-delimited packet mode ({packet, line}).\n"
" In this mode, recv returns one complete line per call.\n"
).
-spec set_line_mode(data_stream()) -> nil.
set_line_mode(Stream) ->
case Stream of
{ssl, Ssl_socket, _} ->
stream_ffi:set_ssl_packet_line(Ssl_socket);
{tcp, Tcp_socket} ->
stream_ffi:set_tcp_packet_line(Tcp_socket)
end.
-file("src/gftp/stream.gleam", 129).
?DOC(
" Set the socket back to raw packet mode ({packet, raw}).\n"
" In this mode, recv returns whatever data is available.\n"
).
-spec set_raw_mode(data_stream()) -> nil.
set_raw_mode(Stream) ->
case Stream of
{ssl, Ssl_socket, _} ->
stream_ffi:set_ssl_packet_raw(Ssl_socket);
{tcp, Tcp_socket} ->
stream_ffi:set_tcp_packet_raw(Tcp_socket)
end.
-file("src/gftp/stream.gleam", 138).
?DOC(
" Shuts down the provided stream, whether it's an SSL or TCP stream.\n"
" It abstracts away the differences between the two types of streams and provides a unified interface for shutting them down.\n"
).
-spec shutdown(data_stream()) -> {ok, nil} | {error, mug:error()}.
shutdown(Stream) ->
case Stream of
{ssl, Ssl_socket, _} ->
kafein_ffi:shutdown(Ssl_socket);
{tcp, Tcp_socket} ->
mug_ffi:shutdown(Tcp_socket)
end.