-module(vlq). -compile([no_auto_import, nowarn_unused_vars, nowarn_unused_function, nowarn_nomatch, inline]). -define(FILEPATH, "src/vlq.gleam"). -export([encode64/1, decode64/1]). -if(?OTP_RELEASE >= 27). -define(MODULEDOC(Str), -moduledoc(Str)). -define(DOC(Str), -doc(Str)). -else. -define(MODULEDOC(Str), -compile([])). -define(DOC(Str), -compile([])). -endif. -file("src/vlq.gleam", 35). -spec index_to_char(integer()) -> binary(). index_to_char(I) -> case I of 0 -> <<"A"/utf8>>; 1 -> <<"B"/utf8>>; 2 -> <<"C"/utf8>>; 3 -> <<"D"/utf8>>; 4 -> <<"E"/utf8>>; 5 -> <<"F"/utf8>>; 6 -> <<"G"/utf8>>; 7 -> <<"H"/utf8>>; 8 -> <<"I"/utf8>>; 9 -> <<"J"/utf8>>; 10 -> <<"K"/utf8>>; 11 -> <<"L"/utf8>>; 12 -> <<"M"/utf8>>; 13 -> <<"N"/utf8>>; 14 -> <<"O"/utf8>>; 15 -> <<"P"/utf8>>; 16 -> <<"Q"/utf8>>; 17 -> <<"R"/utf8>>; 18 -> <<"S"/utf8>>; 19 -> <<"T"/utf8>>; 20 -> <<"U"/utf8>>; 21 -> <<"V"/utf8>>; 22 -> <<"W"/utf8>>; 23 -> <<"X"/utf8>>; 24 -> <<"Y"/utf8>>; 25 -> <<"Z"/utf8>>; 26 -> <<"a"/utf8>>; 27 -> <<"b"/utf8>>; 28 -> <<"c"/utf8>>; 29 -> <<"d"/utf8>>; 30 -> <<"e"/utf8>>; 31 -> <<"f"/utf8>>; 32 -> <<"g"/utf8>>; 33 -> <<"h"/utf8>>; 34 -> <<"i"/utf8>>; 35 -> <<"j"/utf8>>; 36 -> <<"k"/utf8>>; 37 -> <<"l"/utf8>>; 38 -> <<"m"/utf8>>; 39 -> <<"n"/utf8>>; 40 -> <<"o"/utf8>>; 41 -> <<"p"/utf8>>; 42 -> <<"q"/utf8>>; 43 -> <<"r"/utf8>>; 44 -> <<"s"/utf8>>; 45 -> <<"t"/utf8>>; 46 -> <<"u"/utf8>>; 47 -> <<"v"/utf8>>; 48 -> <<"w"/utf8>>; 49 -> <<"x"/utf8>>; 50 -> <<"y"/utf8>>; 51 -> <<"z"/utf8>>; 52 -> <<"0"/utf8>>; 53 -> <<"1"/utf8>>; 54 -> <<"2"/utf8>>; 55 -> <<"3"/utf8>>; 56 -> <<"4"/utf8>>; 57 -> <<"5"/utf8>>; 58 -> <<"6"/utf8>>; 59 -> <<"7"/utf8>>; 60 -> <<"8"/utf8>>; 61 -> <<"9"/utf8>>; 62 -> <<"+"/utf8>>; _ -> <<"/"/utf8>> end. -file("src/vlq.gleam", 26). -spec encode_vlq(integer(), binary()) -> binary(). encode_vlq(Value, Acc) -> Chunk = erlang:'band'(Value, 31), Remaining = erlang:'bsr'(Value, 5), case Remaining of 0 -> <>; _ -> encode_vlq( Remaining, <> ) end. -file("src/vlq.gleam", 149). -spec ascii_to_index(integer()) -> {ok, integer()} | {error, nil}. ascii_to_index(Byte) -> case Byte of _ when (Byte >= 65) andalso (Byte =< 90) -> {ok, Byte - 65}; _ when (Byte >= 97) andalso (Byte =< 122) -> {ok, (Byte - 97) + 26}; _ when (Byte >= 48) andalso (Byte =< 57) -> {ok, (Byte - 48) + 52}; 43 -> {ok, 62}; 47 -> {ok, 63}; _ -> {error, nil} end. -file("src/vlq.gleam", 12). -spec encode_single(integer()) -> binary(). encode_single(N) -> case N =:= -2147483648 of true -> <<"B"/utf8>>; false -> Value = case N < 0 of true -> erlang:'bor'(erlang:'bsl'(- N, 1), 1); false -> erlang:'bsl'(N, 1) end, encode_vlq(Value, <<""/utf8>>) end. -file("src/vlq.gleam", 8). ?DOC(" Encode a series of ints to a base64 VLQ string.\n"). -spec encode64(list(integer())) -> binary(). encode64(Numbers) -> gleam@list:fold( Numbers, <<""/utf8>>, fun(Acc, N) -> <> end ). -file("src/vlq.gleam", 139). -spec decode_value(integer()) -> integer(). decode_value(Encoded) -> Sign = erlang:'band'(Encoded, 1), Magnitude = erlang:'bsr'(Encoded, 1), case {Sign, Magnitude} of {1, 0} -> -2147483648; {1, _} -> - Magnitude; {_, _} -> Magnitude end. -file("src/vlq.gleam", 109). -spec decode_bytes(bitstring(), integer(), integer(), list(integer())) -> {ok, list(integer())} | {error, nil}. decode_bytes(Bytes, Acc, Shift, Results) -> case Bytes of <> -> case ascii_to_index(Byte) of {error, nil} -> {error, nil}; {ok, Index} -> Chunk = erlang:'band'(Index, 31), New_acc = erlang:'bor'(Acc, erlang:'bsl'(Chunk, Shift)), Continuation = erlang:'band'(Index, 32) /= 0, case Continuation of true -> decode_bytes(Rest, New_acc, Shift + 5, Results); false -> Value = decode_value(New_acc), decode_bytes(Rest, 0, 0, [Value | Results]) end end; <<>> -> {ok, lists:reverse(Results)}; _ -> {error, nil} end. -file("src/vlq.gleam", 105). ?DOC(" Dencode a base64 VLQ string to a series of ints.\n"). -spec decode64(binary()) -> {ok, list(integer())} | {error, nil}. decode64(S) -> decode_bytes(gleam_stdlib:identity(S), 0, 0, []).