-module(internal@encoder@bit). -compile([no_auto_import, nowarn_unused_vars, nowarn_unused_function, nowarn_nomatch, inline]). -define(FILEPATH, "src/internal/encoder/bit.gleam"). -export([estimate_encoded_size/4, 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( " Encode bit strings according to RFC 2045.\n" "\n" " See the following link for reference:\n" " - \n" " - \n" ). -file("src/internal/encoder/bit.gleam", 113). -spec is_valid_character(binary(), gleam@option:option(binary())) -> boolean(). is_valid_character(Character, Max_ascii) -> (((gleam@string:compare(Character, <<"\r"/utf8>>) /= eq) andalso (gleam@string:compare( Character, <<"\n"/utf8>> ) /= eq)) andalso (gleam@string:compare(Character, <<"\x{0}"/utf8>>) =:= gt)) andalso begin _pipe = Max_ascii, _pipe@1 = gleam@option:map( _pipe, fun(Ascii) -> gleam@string:compare(Character, Ascii) =:= lt end ), gleam@option:unwrap(_pipe@1, true) end. -file("src/internal/encoder/bit.gleam", 91). -spec validate_line(binary(), gleam@option:option(binary()), integer()) -> {ok, integer()} | {error, internal@encoder@encoding:encoder_error()}. validate_line(Line, Max_ascii, Maximum_size) -> Line_size = erlang:byte_size(Line), gleam@bool:guard( Line_size > Maximum_size, {error, {maximum_size_exceeded, Maximum_size}}, fun() -> Validation = begin _pipe = Line, _pipe@1 = gleam@string:split(_pipe, <<""/utf8>>), gleam@list:find( _pipe@1, fun(Character) -> not is_valid_character(Character, Max_ascii) end ) end, case Validation of {ok, Character@1} -> {error, {invalid_character, Character@1}}; {error, nil} -> {ok, Line_size} end end ). -file("src/internal/encoder/bit.gleam", 64). -spec max_ascii_from_bits(integer(), internal@encoder@encoding:encoding_mode()) -> gleam@option:option(binary()). max_ascii_from_bits(Bits, Mode) -> case {Bits, Mode} of {8, utf8} -> none; {_, ascii} -> _pipe = gleam@int:power(2, erlang:float(Bits)), _pipe@1 = gleam@result:map( _pipe, fun(Ascii_code) -> gleam@int:min(erlang:trunc(Ascii_code) - 1, 127) end ), _pipe@2 = gleam@result:'try'( _pipe@1, fun gleam@string:utf_codepoint/1 ), _pipe@3 = gleam@result:map( _pipe@2, fun(Codepoint) -> gleam_stdlib:utf_codepoint_list_to_string([Codepoint]) end ), _pipe@4 = gleam@result:unwrap(_pipe@3, <<""/utf8>>), {some, _pipe@4}; {_, utf8} -> _pipe@5 = gleam@int:power(2, erlang:float(Bits)), _pipe@6 = gleam@result:map( _pipe@5, fun(Ascii_code@1) -> erlang:trunc(Ascii_code@1) - 1 end ), _pipe@7 = gleam@result:'try'( _pipe@6, fun gleam@string:utf_codepoint/1 ), _pipe@8 = gleam@result:map( _pipe@7, fun(Codepoint@1) -> gleam_stdlib:utf_codepoint_list_to_string([Codepoint@1]) end ), _pipe@9 = gleam@result:unwrap(_pipe@8, <<""/utf8>>), {some, _pipe@9} end. -file("src/internal/encoder/bit.gleam", 20). ?DOC( " Estimates the `bits' bit encoded size of a string in bytes, taking\n" " maximum size of a line into account.\n" ). -spec estimate_encoded_size( binary(), integer(), internal@encoder@encoding:encoding_mode(), integer() ) -> {ok, integer()} | {error, internal@encoder@encoding:encoder_error()}. estimate_encoded_size(String, Bits, Mode, Maximum_size) -> Max_ascii = max_ascii_from_bits(Bits, Mode), _pipe = String, _pipe@1 = gleam@string:split(_pipe, <<"\r\n"/utf8>>), gleam@list:try_fold( _pipe@1, 0, fun(Size, Line) -> case validate_line(Line, Max_ascii, Maximum_size) of {ok, Line_size} -> {ok, Size + Line_size}; {error, _} = Error -> Error end end ). -file("src/internal/encoder/bit.gleam", 41). ?DOC( " Bit encode a string with the required number of bits, using the\n" " specified encoding mode and taking into account the maximum allowed\n" " line size.\n" ). -spec encode_string( binary(), integer(), internal@encoder@encoding:encoding_mode(), integer() ) -> {ok, list(binary())} | {error, internal@encoder@encoding:encoder_error()}. encode_string(String, Bits, Mode, Maximum_size) -> case String of <<""/utf8>> -> {ok, []}; _ -> Max_ascii = max_ascii_from_bits(Bits, Mode), _pipe = String, _pipe@1 = gleam@string:split(_pipe, <<"\r\n"/utf8>>), gleam@list:try_map( _pipe@1, fun(Line) -> case validate_line(Line, Max_ascii, Maximum_size) of {ok, _} -> {ok, Line}; {error, Error} -> {error, Error} end end ) end.