-module(multipartkit@internal@disposition). -compile([no_auto_import, nowarn_unused_vars, nowarn_unused_function, nowarn_nomatch, inline]). -define(FILEPATH, "src/multipartkit/internal/disposition.gleam"). -export([sanitize_value/1, has_header_breaking_bytes/1, build_form_data_value/2]). -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(false). -file("src/multipartkit/internal/disposition.gleam", 39). ?DOC(false). -spec sanitize_value(binary()) -> binary(). sanitize_value(Value) -> _pipe = Value, _pipe@1 = gleam@string:replace(_pipe, <<"\r\n"/utf8>>, <<""/utf8>>), _pipe@2 = gleam@string:replace(_pipe@1, <<"\r"/utf8>>, <<""/utf8>>), _pipe@3 = gleam@string:replace(_pipe@2, <<"\n"/utf8>>, <<""/utf8>>), gleam@string:replace(_pipe@3, <<"\x{0000}"/utf8>>, <<""/utf8>>). -file("src/multipartkit/internal/disposition.gleam", 49). ?DOC(false). -spec has_header_breaking_bytes(binary()) -> boolean(). has_header_breaking_bytes(Value) -> (gleam_stdlib:contains_string(Value, <<"\r"/utf8>>) orelse gleam_stdlib:contains_string( Value, <<"\n"/utf8>> )) orelse gleam_stdlib:contains_string(Value, <<"\x{0000}"/utf8>>). -file("src/multipartkit/internal/disposition.gleam", 70). ?DOC(false). -spec is_ascii_safe_loop(bitstring()) -> boolean(). is_ascii_safe_loop(Bytes) -> case Bytes of <<>> -> true; <> -> case (B =:= 16#09) orelse ((B >= 16#20) andalso (B =< 16#7E)) of true -> is_ascii_safe_loop(Rest); false -> false end; _ -> false end. -file("src/multipartkit/internal/disposition.gleam", 66). ?DOC(false). -spec is_ascii_safe(binary()) -> boolean(). is_ascii_safe(S) -> is_ascii_safe_loop(gleam_stdlib:identity(S)). -file("src/multipartkit/internal/disposition.gleam", 86). ?DOC(false). -spec ascii_fallback_loop(list(binary()), binary()) -> binary(). ascii_fallback_loop(Remaining, Acc) -> case Remaining of [] -> Acc; [Grapheme | Rest] -> case is_ascii_safe(Grapheme) of true -> ascii_fallback_loop(Rest, <>); false -> ascii_fallback_loop(Rest, <>) end end. -file("src/multipartkit/internal/disposition.gleam", 82). ?DOC(false). -spec ascii_fallback(binary()) -> binary(). ascii_fallback(S) -> ascii_fallback_loop(gleam@string:to_graphemes(S), <<""/utf8>>). -file("src/multipartkit/internal/disposition.gleam", 115). ?DOC(false). -spec is_attr_char(integer()) -> boolean(). is_attr_char(B) -> (((((((((((((((B >= 16#41) andalso (B =< 16#5A)) orelse ((B >= 16#61) andalso (B =< 16#7A))) orelse ((B >= 16#30) andalso (B =< 16#39))) orelse (B =:= 16#21)) orelse (B =:= 16#23)) orelse (B =:= 16#24)) orelse (B =:= 16#26)) orelse (B =:= 16#2B)) orelse (B =:= 16#2D)) orelse (B =:= 16#2E)) orelse (B =:= 16#5E)) orelse (B =:= 16#5F)) orelse (B =:= 16#60)) orelse (B =:= 16#7C)) orelse (B =:= 16#7E). -file("src/multipartkit/internal/disposition.gleam", 139). ?DOC(false). -spec hex_digit(integer()) -> binary(). hex_digit(N) -> case N of 0 -> <<"0"/utf8>>; 1 -> <<"1"/utf8>>; 2 -> <<"2"/utf8>>; 3 -> <<"3"/utf8>>; 4 -> <<"4"/utf8>>; 5 -> <<"5"/utf8>>; 6 -> <<"6"/utf8>>; 7 -> <<"7"/utf8>>; 8 -> <<"8"/utf8>>; 9 -> <<"9"/utf8>>; 10 -> <<"A"/utf8>>; 11 -> <<"B"/utf8>>; 12 -> <<"C"/utf8>>; 13 -> <<"D"/utf8>>; 14 -> <<"E"/utf8>>; 15 -> <<"F"/utf8>>; _ -> erlang:integer_to_binary(N) end. -file("src/multipartkit/internal/disposition.gleam", 135). ?DOC(false). -spec percent_byte(integer()) -> binary(). percent_byte(B) -> <<<<"%"/utf8, (hex_digit(B div 16))/binary>>/binary, (hex_digit(B rem 16))/binary>>. -file("src/multipartkit/internal/disposition.gleam", 101). ?DOC(false). -spec percent_encode_loop(bitstring(), binary()) -> binary(). percent_encode_loop(Bytes, Acc) -> case Bytes of <<>> -> Acc; <> -> Chunk = case is_attr_char(B) of false -> percent_byte(B); true -> _pipe = gleam@bit_array:to_string(<>), gleam@result:unwrap(_pipe, percent_byte(B)) end, percent_encode_loop(Rest, <>); _ -> Acc end. -file("src/multipartkit/internal/disposition.gleam", 97). ?DOC(false). -spec percent_encode_rfc5987(binary()) -> binary(). percent_encode_rfc5987(S) -> percent_encode_loop(gleam_stdlib:identity(S), <<""/utf8>>). -file("src/multipartkit/internal/disposition.gleam", 165). ?DOC(false). -spec escape_quoted(binary(), binary()) -> binary(). escape_quoted(Remaining, Acc) -> case gleam_stdlib:string_pop_grapheme(Remaining) of {error, nil} -> Acc; {ok, {<<"\\"/utf8>>, Rest}} -> escape_quoted(Rest, <>); {ok, {<<"\""/utf8>>, Rest@1}} -> escape_quoted(Rest@1, <>); {ok, {Other, Rest@2}} -> escape_quoted(Rest@2, <>) end. -file("src/multipartkit/internal/disposition.gleam", 161). ?DOC(false). -spec quote(binary()) -> binary(). quote(Value) -> <<<<"\""/utf8, (escape_quoted(Value, <<""/utf8>>))/binary>>/binary, "\""/utf8>>. -file("src/multipartkit/internal/disposition.gleam", 55). ?DOC(false). -spec filename_disposition_params(binary()) -> binary(). filename_disposition_params(Filename) -> case is_ascii_safe(Filename) of true -> <<"; filename="/utf8, (quote(Filename))/binary>>; false -> <<<<<<"; filename="/utf8, (quote(ascii_fallback(Filename)))/binary>>/binary, "; filename*=UTF-8''"/utf8>>/binary, (percent_encode_rfc5987(Filename))/binary>> end. -file("src/multipartkit/internal/disposition.gleam", 27). ?DOC(false). -spec build_form_data_value(binary(), gleam@option:option(binary())) -> binary(). build_form_data_value(Name, Filename) -> Base = <<"form-data; name="/utf8, (quote(Name))/binary>>, case Filename of none -> Base; {some, Fname} -> <> end.