-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]). -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/gleb128.gleam", 7). -spec do_encode_unsigned(integer(), gleam@bytes_tree:bytes_tree()) -> {ok, gleam@bytes_tree:bytes_tree()} | {error, nil}. 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_tree:append(Builder, <>)}; _ -> Current_chunk@1 = erlang:'bor'(Current_chunk, 2#10000000), do_encode_unsigned( Next_chunk, gleam@bytes_tree:append(Builder, <>) ) end; false -> {error, nil} end. -file("src/gleb128.gleam", 40). -spec do_encode_signed(integer(), gleam@bytes_tree:bytes_tree()) -> gleam@bytes_tree:bytes_tree(). 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_tree:append(Builder, <>); _ -> Current_chunk@1 = erlang:'bor'(Current_chunk, 2#10000000), do_encode_signed( Next_chunk, gleam@bytes_tree:append(Builder, <>) ) end. -file("src/gleb128.gleam", 76). -spec do_decode_unsigned(bitstring(), integer(), integer(), integer()) -> {ok, {integer(), integer()}} | {error, nil}. 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, nil} end; _ -> {error, nil} end. -file("src/gleb128.gleam", 109). -spec do_decode_signed(bitstring(), integer(), integer(), integer()) -> {ok, {integer(), integer()}} | {error, nil}. 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, nil} end; _ -> {error, nil} end. -file("src/gleb128.gleam", 155). -spec do_fast_decode_unsigned(integer(), integer(), integer(), integer()) -> {ok, {integer(), integer()}} | {error, nil}. 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. -file("src/gleb128.gleam", 178). -spec do_fast_decode_signed(integer(), integer(), integer(), integer()) -> {ok, {integer(), integer()}} | {error, nil}. 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. -file("src/gleb128.gleam", 217). ?DOC( " Encodes an unsigned (positive) integer to a bit array containing its LEB128 representation.\n" "\n" " Returns an error when the given value to encode is negative.\n" ). -spec encode_unsigned(integer()) -> {ok, bitstring()} | {error, nil}. encode_unsigned(Value) -> case do_encode_unsigned(Value, gleam@bytes_tree:new()) of {ok, Result} -> {ok, erlang:list_to_bitstring(Result)}; {error, E} -> {error, E} end. -file("src/gleb128.gleam", 227). ?DOC(" Encodes an signed (positive or negative) integer to a bit array containing its LEB128 representation.\n"). -spec encode_signed(integer()) -> bitstring(). encode_signed(Value) -> _pipe = do_encode_signed(Value, gleam@bytes_tree:new()), erlang:list_to_bitstring(_pipe). -file("src/gleb128.gleam", 243). ?DOC( " Decodes a bit array containing some LEB128 integer as an unsigned (positive) integer.\n" " \n" " Returns a tuple containing the decoded value in its first position, followed by the count of\n" " bytes read in its second position. Returns an error when the given data can't be decoded.\n" " \n" " This function is designed to optimize small inputs (whose length is less than or equal to 8 bytes)\n" " by treating them as integers; since the input size is close to the word size of a 64-bit CPU,\n" " the Erlang runtime will internally treat it as a \"native\" integer and not as a bignum/boxed integer\n" " (which are stored on the heap and referenced via pointers), thus significantly reducing memory\n" " consumption and speeding up arithmetic operations. See [erl_arith.c](https://github.com/erlang/otp/blob/55d43cd555e78b9071e514b42834ae31e2081f59/erts/emulator/beam/erl_arith.c#L146C1-L146C11).\n" ). -spec decode_unsigned(bitstring()) -> {ok, {integer(), integer()}} | {error, nil}. decode_unsigned(Data) -> case erlang:byte_size(Data) of Size when Size =< 8 -> case gleam_stdlib:bit_array_slice( <>, 0, 8 ) of {ok, <>} -> do_fast_decode_unsigned(Value, 0, 0, 0); _ -> {error, nil} end; _ -> do_decode_unsigned(Data, 0, 0, 0) end. -file("src/gleb128.gleam", 266). ?DOC( " Decodes a bit array containing some LEB128 integer as an signed (positive or negative) integer.\n" " \n" " Returns a tuple containing the decoded value in its first position, followed by the count of\n" " bytes read in its second position. Returns an error when the given data can't be decoded.\n" " \n" " This function is designed to optimize small inputs (whose length is less than or equal to 8 bytes)\n" " by treating them as integers; since the input size is close to the word size of a 64-bit CPU,\n" " the Erlang runtime will internally treat it as a \"native\" integer and not as a bignum/boxed integer\n" " (which are stored on the heap and referenced via pointers), thus significantly reducing memory\n" " consumption and speeding up arithmetic operations. See [erl_arith.c](https://github.com/erlang/otp/blob/55d43cd555e78b9071e514b42834ae31e2081f59/erts/emulator/beam/erl_arith.c#L146C1-L146C11).\n" ). -spec decode_signed(bitstring()) -> {ok, {integer(), integer()}} | {error, nil}. decode_signed(Data) -> case erlang:byte_size(Data) of Size when Size =< 8 -> case gleam_stdlib:bit_array_slice( <>, 0, 8 ) of {ok, <>} -> do_fast_decode_signed(Value, 0, 0, 0); _ -> {error, nil} end; _ -> do_decode_signed(Data, 0, 0, 0) end.