Skip to main content

src/internal@encoder@base64.erl

-module(internal@encoder@base64).
-compile([no_auto_import, nowarn_unused_vars, nowarn_unused_function, nowarn_nomatch, inline]).
-define(FILEPATH, "src/internal/encoder/base64.gleam").
-export([estimate_encoded_size/1, encode_string/3]).

-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 base64 strings according to RFC 2045.\n"
    "\n"
    " See the following link for reference:\n"
    " - <https://tools.ietf.org/html/rfc2045>\n"
).

-file("src/internal/encoder/base64.gleam", 14).
?DOC(" Estimates the base64 encoded size of a string in bytes.\n").
-spec estimate_encoded_size(binary()) -> {ok, integer()} |
    {error, internal@encoder@encoding:encoder_error()}.
estimate_encoded_size(String) ->
    {ok, (erlang:byte_size(String) * 8) div 6}.

-file("src/internal/encoder/base64.gleam", 38).
-spec chunk(list(binary()), integer(), integer()) -> list(binary()).
chunk(Characters, Used_size, Chunk_size) ->
    _pipe = Characters,
    _pipe@1 = gleam@list:fold(
        _pipe,
        {Used_size, []},
        fun(Accumulator, Character) ->
            {Used_size@1, Chunks} = Accumulator,
            Character_size = erlang:byte_size(Character),
            case Chunks of
                [] ->
                    {Character_size, [Character]};

                [Chunk | Other_chunks] when (Used_size@1 + Character_size) =< Chunk_size ->
                    {Used_size@1 + Character_size,
                        [<<Chunk/binary, Character/binary>> | Other_chunks]};

                Chunks@1 ->
                    {Character_size, [Character | Chunks@1]}
            end
        end
    ),
    _pipe@2 = gleam@pair:second(_pipe@1),
    lists:reverse(_pipe@2).

-file("src/internal/encoder/base64.gleam", 23).
?DOC(
    " Base64 encode a string, taking the preferred line size into\n"
    " account and pretending to start the first line at the passed\n"
    " start position.\n"
).
-spec encode_string(binary(), integer(), integer()) -> {ok, list(binary())} |
    {error, internal@encoder@encoding:encoder_error()}.
encode_string(String, Position, Preferred_size) ->
    Chunk_size = (Preferred_size * 6) div 8,
    _pipe = String,
    _pipe@1 = gleam@string:split(_pipe, <<""/utf8>>),
    _pipe@2 = chunk(_pipe@1, Position, Chunk_size),
    _pipe@3 = gleam@list:map(_pipe@2, fun gleam_stdlib:identity/1),
    _pipe@4 = gleam@list:map(
        _pipe@3,
        fun(_capture) -> gleam_stdlib:base64_encode(_capture, true) end
    ),
    {ok, _pipe@4}.