-module(internal@encoder@quoted_printable).
-compile([no_auto_import, nowarn_unused_vars, nowarn_unused_function, nowarn_nomatch, inline]).
-define(FILEPATH, "src/internal/encoder/quoted_printable.gleam").
-export([estimate_encoded_size/2, encode_string/4]).
-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(
" Encodes quoted-printable strings according to RFC 2045\n"
" and RFC 2047.\n"
"\n"
" See the following links for reference:\n"
" - <https://tools.ietf.org/html/rfc2045#section-6.7>\n"
" - <https://tools.ietf.org/html/rfc2047>\n"
).
-file("src/internal/encoder/quoted_printable.gleam", 91).
-spec should_encode_character(binary(), internal@encoder@encoding:rfc()) -> boolean().
should_encode_character(Character, Rfc) ->
(Character /= <<"\t"/utf8>>) andalso ((((gleam@string:compare(
Character,
<<"\x{20}"/utf8>>
)
=:= lt)
orelse (gleam@string:compare(Character, <<"\x{7f}"/utf8>>) =:= gt))
orelse (gleam@string:compare(Character, <<"="/utf8>>) =:= eq))
orelse ((Rfc =:= rfc2047) andalso gleam_stdlib:contains_string(
<<"()<>@,;:\"/[]?._"/utf8>>,
Character
))).
-file("src/internal/encoder/quoted_printable.gleam", 19).
?DOC(
" Estimates the quoted printable encoded size of a string in bytes,\n"
" taking the desired RFC constraints into account.\n"
).
-spec estimate_encoded_size(binary(), internal@encoder@encoding:rfc()) -> {ok,
integer()} |
{error, internal@encoder@encoding:encoder_error()}.
estimate_encoded_size(String, Rfc) ->
_pipe = String,
_pipe@1 = gleam@string:split(_pipe, <<""/utf8>>),
_pipe@2 = gleam@list:fold(
_pipe@1,
0,
fun(Size, Character) ->
Character_size = erlang:byte_size(Character),
case should_encode_character(Character, Rfc) of
true ->
Size + (3 * Character_size);
false ->
Size + Character_size
end
end
),
{ok, _pipe@2}.
-file("src/internal/encoder/quoted_printable.gleam", 117).
-spec do_encode_bytes(bitstring(), list(binary())) -> binary().
do_encode_bytes(Bytes, Accumulator) ->
case Bytes of
<<Byte:1/binary, Other_bytes/binary>> ->
do_encode_bytes(
Other_bytes,
[<<"="/utf8, (gleam_stdlib:base16_encode(Byte))/binary>> |
Accumulator]
);
<<_/bitstring>> ->
_pipe = Accumulator,
_pipe@1 = lists:reverse(_pipe),
gleam@string:join(_pipe@1, <<""/utf8>>)
end.
-file("src/internal/encoder/quoted_printable.gleam", 106).
-spec encode_character(binary(), internal@encoder@encoding:rfc(), boolean()) -> binary().
encode_character(Character, Rfc, Force_encoding) ->
Should_encode = should_encode_character(Character, Rfc) orelse Force_encoding,
gleam@bool:guard(
not Should_encode,
Character,
fun() -> do_encode_bytes(gleam_stdlib:identity(Character), []) end
).
-file("src/internal/encoder/quoted_printable.gleam", 101).
-spec is_whitespace(binary()) -> boolean().
is_whitespace(Character) ->
(gleam@string:compare(Character, <<"\t"/utf8>>) =:= eq) orelse (gleam@string:compare(
Character,
<<" "/utf8>>
)
=:= eq).
-file("src/internal/encoder/quoted_printable.gleam", 51).
-spec do_encode_string(
list(binary()),
internal@encoder@encoding:rfc(),
integer(),
{integer(), list(binary())}
) -> {ok, list(binary())} | {error, internal@encoder@encoding:encoder_error()}.
do_encode_string(Characters, Rfc, Preferred_size, Accumulator) ->
{Used_size, Lines} = Accumulator,
case Characters of
[] ->
{ok, Lines};
[Character | Other_characters] ->
Force_encoding = is_whitespace(Character) andalso gleam@list:is_empty(
Other_characters
),
Encoded_character = encode_character(Character, Rfc, Force_encoding),
Encoded_character_size = erlang:byte_size(Encoded_character),
_pipe = case Lines of
[] ->
{Encoded_character_size, [Encoded_character]};
[First_line | Other_lines] when ((Used_size + Encoded_character_size) < Preferred_size) orelse ((Other_characters =:= []) andalso ((Used_size + Encoded_character_size) =:= Preferred_size)) ->
{Used_size + Encoded_character_size,
[<<First_line/binary, Encoded_character/binary>> |
Other_lines]};
[First_line@1 | Other_lines@1] ->
{Encoded_character_size,
[Encoded_character,
<<First_line@1/binary, "="/utf8>> |
Other_lines@1]}
end,
do_encode_string(Other_characters, Rfc, Preferred_size, _pipe)
end.
-file("src/internal/encoder/quoted_printable.gleam", 39).
?DOC(
" Quoted printable encode a string, taking the desired RFC\n"
" constraints and the preferred line size into account, and\n"
" pretending to start the first line at the passed start position.\n"
).
-spec encode_string(
binary(),
internal@encoder@encoding:rfc(),
integer(),
integer()
) -> {ok, list(binary())} | {error, internal@encoder@encoding:encoder_error()}.
encode_string(String, Rfc, Position, Preferred_size) ->
_pipe = String,
_pipe@1 = gleam@string:split(_pipe, <<""/utf8>>),
_pipe@2 = do_encode_string(_pipe@1, Rfc, Preferred_size, {Position, []}),
gleam@result:map(_pipe@2, fun lists:reverse/1).