-module(gleb128). -compile([no_auto_import, nowarn_unused_vars, nowarn_unused_function, nowarn_nomatch]). -export([encode_unsigned/1, encode_signed/1, decode_unsigned/1, decode_signed/1, fast_decode_unsigned/1, fast_decode_signed/1]). -spec do_encode_unsigned(integer(), gleam@bytes_builder:bytes_builder()) -> {ok, gleam@bytes_builder:bytes_builder()} | {error, binary()}. do_encode_unsigned(Value, Builder) -> case Value >= 0 of true -> Current_chunk = erlang:'band'(Value, 2#01111111), Next_chunk = erlang:'bsr'(Value, 7), case Next_chunk of 0 -> {ok, gleam@bytes_builder:append(Builder, <>)}; _ -> Current_chunk@1 = erlang:'bor'(Current_chunk, 2#10000000), do_encode_unsigned( Next_chunk, gleam@bytes_builder:append(Builder, <>) ) end; false -> {error, <<"Can't encode a negative value with an unsigned function"/utf8>>} end. -spec do_encode_signed(integer(), gleam@bytes_builder:bytes_builder()) -> gleam@bytes_builder:bytes_builder(). do_encode_signed(Value, Builder) -> Current_chunk = erlang:'band'(Value, 2#01111111), Next_chunk = erlang:'bsr'(Value, 7), Sign = erlang:'band'(Value, 2#01000000), Sign@1 = erlang:'bsr'(Sign, 6), case ((Next_chunk =:= 0) andalso (Sign@1 =:= 0)) orelse ((Next_chunk =:= erlang:'bnot'( 0 )) andalso (Sign@1 =:= 1)) of true -> gleam@bytes_builder:append(Builder, <>); _ -> Current_chunk@1 = erlang:'bor'(Current_chunk, 2#10000000), do_encode_signed( Next_chunk, gleam@bytes_builder:append(Builder, <>) ) end. -spec do_decode_unsigned(bitstring(), integer(), integer(), integer()) -> {ok, {integer(), integer()}} | {error, binary()}. do_decode_unsigned( Data, Position_accumulator, Result_accumulator, Shift_accumulator ) -> case gleam_stdlib:bit_array_slice(Data, Position_accumulator, 1) of {ok, Slice} -> case Slice of <> -> Current_chunk = erlang:'band'(Byte, 2#01111111), Current_chunk@1 = erlang:'bsl'( Current_chunk, Shift_accumulator ), Result_accumulator@1 = erlang:'bor'( Result_accumulator, Current_chunk@1 ), Next_chunk = erlang:'bsr'(Byte, 7), case Next_chunk of 0 -> {ok, {Result_accumulator@1, Position_accumulator + 1}}; _ -> do_decode_unsigned( Data, Position_accumulator + 1, Result_accumulator@1, Shift_accumulator + 7 ) end; _ -> {error, <<"Can't decode the bit array slice into a byte"/utf8>>} end; _ -> {error, <<"Invalid LEB128 integer"/utf8>>} end. -spec do_decode_signed(bitstring(), integer(), integer(), integer()) -> {ok, {integer(), integer()}} | {error, binary()}. do_decode_signed( Data, Position_accumulator, Result_accumulator, Shift_accumulator ) -> case gleam_stdlib:bit_array_slice(Data, Position_accumulator, 1) of {ok, Slice} -> case Slice of <> -> Current_chunk = erlang:'band'(Byte, 2#01111111), Current_chunk@1 = erlang:'bsl'( Current_chunk, Shift_accumulator ), Result_accumulator@1 = erlang:'bor'( Result_accumulator, Current_chunk@1 ), Shift_accumulator@1 = Shift_accumulator + 7, Next_chunk = erlang:'bsr'(Byte, 7), case Next_chunk of 0 -> Sign = erlang:'band'(Byte, 2#01000000), Sign@1 = erlang:'bsr'(Sign, 6), case Sign@1 of 1 -> {ok, {erlang:'bor'( Result_accumulator@1, erlang:'bsl'( erlang:'bnot'(0), Shift_accumulator@1 ) ), Position_accumulator + 1}}; _ -> {ok, {Result_accumulator@1, Position_accumulator + 1}} end; _ -> do_decode_signed( Data, Position_accumulator + 1, Result_accumulator@1, Shift_accumulator@1 ) end; _ -> {error, <<"Can't decode the bit array slice into a byte"/utf8>>} end; _ -> {error, <<"Invalid LEB128 integer"/utf8>>} end. -spec do_fast_decode_unsigned(integer(), integer(), integer(), integer()) -> {ok, {integer(), integer()}} | {error, binary()}. do_fast_decode_unsigned( Data, Position_accumulator, Result_accumulator, Shift_accumulator ) -> Byte = erlang:'bsr'(Data, 8 * Position_accumulator), Byte@1 = erlang:'band'(Byte, 16#ff), Current_chunk = erlang:'band'(Byte@1, 2#01111111), Current_chunk@1 = erlang:'bsl'(Current_chunk, Shift_accumulator), Result_accumulator@1 = erlang:'bor'(Result_accumulator, Current_chunk@1), Next_chunk = erlang:'bsr'(Byte@1, 7), case Next_chunk of 0 -> {ok, {Result_accumulator@1, Position_accumulator + 1}}; _ -> do_fast_decode_unsigned( Data, Position_accumulator + 1, Result_accumulator@1, Shift_accumulator + 7 ) end. -spec do_fast_decode_signed(integer(), integer(), integer(), integer()) -> {ok, {integer(), integer()}} | {error, binary()}. do_fast_decode_signed( Data, Position_accumulator, Result_accumulator, Shift_accumulator ) -> Byte = erlang:'bsr'(Data, 8 * Position_accumulator), Byte@1 = erlang:'band'(Byte, 16#ff), Current_chunk = erlang:'band'(Byte@1, 2#01111111), Current_chunk@1 = erlang:'bsl'(Current_chunk, Shift_accumulator), Result_accumulator@1 = erlang:'bor'(Result_accumulator, Current_chunk@1), Shift_accumulator@1 = Shift_accumulator + 7, Next_chunk = erlang:'bsr'(Byte@1, 7), case Next_chunk of 0 -> Sign = erlang:'band'(Byte@1, 2#01000000), Sign@1 = erlang:'bsr'(Sign, 6), case Sign@1 of 1 -> {ok, {erlang:'bor'( Result_accumulator@1, erlang:'bsl'( erlang:'bnot'(0), Shift_accumulator@1 ) ), Position_accumulator + 1}}; _ -> {ok, {Result_accumulator@1, Position_accumulator + 1}} end; _ -> do_fast_decode_signed( Data, Position_accumulator + 1, Result_accumulator@1, Shift_accumulator@1 ) end. -spec encode_unsigned(integer()) -> {ok, bitstring()} | {error, binary()}. encode_unsigned(Value) -> case do_encode_unsigned(Value, gleam@bytes_builder:new()) of {ok, Result} -> {ok, erlang:list_to_bitstring(Result)}; {error, E} -> {error, E} end. -spec encode_signed(integer()) -> bitstring(). encode_signed(Value) -> _pipe = do_encode_signed(Value, gleam@bytes_builder:new()), erlang:list_to_bitstring(_pipe). -spec decode_unsigned(bitstring()) -> {ok, {integer(), integer()}} | {error, binary()}. decode_unsigned(Data) -> do_decode_unsigned(Data, 0, 0, 0). -spec decode_signed(bitstring()) -> {ok, {integer(), integer()}} | {error, binary()}. decode_signed(Data) -> do_decode_signed(Data, 0, 0, 0). -spec fast_decode_unsigned(bitstring()) -> {ok, {integer(), integer()}} | {error, binary()}. fast_decode_unsigned(Data) -> case erlang:byte_size(Data) of S when S =< 8 -> do_fast_decode_unsigned( binary:decode_unsigned(Data, little), 0, 0, 0 ); _ -> do_decode_unsigned(Data, 0, 0, 0) end. -spec fast_decode_signed(bitstring()) -> {ok, {integer(), integer()}} | {error, binary()}. fast_decode_signed(Data) -> case erlang:byte_size(Data) of S when S =< 8 -> do_fast_decode_signed( gleb128@internal@native:decode_native_signed_integer( Data, little ), 0, 0, 0 ); _ -> do_decode_signed(Data, 0, 0, 0) end.