Skip to content

Instantly share code, notes, and snippets.

@hntrmrrs
Created August 2, 2011 16:43
Show Gist options
  • Save hntrmrrs/1120616 to your computer and use it in GitHub Desktop.
Save hntrmrrs/1120616 to your computer and use it in GitHub Desktop.

Revisions

  1. Hunter Morris revised this gist Aug 4, 2011. 1 changed file with 10 additions and 22 deletions.
    32 changes: 10 additions & 22 deletions uleb128.erl
    Original file line number Diff line number Diff line change
    @@ -8,30 +8,18 @@
    -export([prop_encode_decode/0]).

    -spec encode(non_neg_integer()) -> binary().
    encode(I) when I >= 0, I =< 16#7f -> <<I:8>>;
    encode(I) when I > 16#7f, I =< 16#3fff ->
    I1 = (((I band 16#7f) bor 16#80) bsl 8) bor ((I bsr 7) band 16#7f),
    <<I1:16>>;
    encode(I) when I > 16#3fff, I =< 16#1fffff ->
    I1 = ((I bsr 14) band 16#7f) bor
    ((((I bsr 7) band 16#7f) bor 16#80) bsl 8) bor
    (((I band 16#7f) bor 16#80) bsl 16),
    <<I1:24>>;
    encode(I) when I > 16#1fffff, I =< 16#fffffff ->
    I1 = ((I bsr 21) band 16#7f) bor
    ((((I bsr 14) band 16#7f) bor 16#80) bsl 8) bor
    ((((I bsr 7) band 16#7f) bor 16#80) bsl 16) bor
    (((I band 16#7f) bor 16#80) bsl 24),
    <<I1:32>>;
    encode(I) when I >= 0 -> encode(I, <<>>).
    encode(I) when I >= 0 -> encode_1(I, 0).

    -spec encode(non_neg_integer(), binary()) -> binary().
    encode(I, Acc) when I =< 16#7f ->
    <<Acc/binary, I:8>>;
    encode(I, Acc) ->
    I1 = (I bsr 7),
    Val = (I - (I1 bsl 7)) bor 16#80,
    encode(I1, <<Acc/binary, Val:8>>).
    encode(I, Acc) -> <<Acc/binary, (encode_1(I, 0))/binary>>.

    -spec encode_1(non_neg_integer(),
    non_neg_integer()) -> binary().
    encode_1(I, Acc) when I > 16#7f ->
    Val = I band 16#7f bor 16#80,
    encode_1(I bsr 7, Acc bsl 8 bor Val);
    encode_1(I, Acc) ->
    binary:encode_unsigned(Acc bsl 8 bor I).

    -type decode_cont() :: {cont,
    non_neg_integer(),
  2. Hunter Morris revised this gist Aug 3, 2011. 1 changed file with 1 addition and 1 deletion.
    2 changes: 1 addition & 1 deletion uleb128.erl
    Original file line number Diff line number Diff line change
    @@ -1,7 +1,7 @@

    -module(uleb128).

    -export([encode/1, decode/1, decode/2]).
    -export([encode/1, encode/2, decode/1, decode/2]).

    % For property tests
    -include_lib("proper/include/proper.hrl").
  3. Hunter Morris revised this gist Aug 3, 2011. 1 changed file with 5 additions and 5 deletions.
    10 changes: 5 additions & 5 deletions uleb128.erl
    Original file line number Diff line number Diff line change
    @@ -23,15 +23,15 @@ encode(I) when I > 16#1fffff, I =< 16#fffffff ->
    ((((I bsr 7) band 16#7f) bor 16#80) bsl 16) bor
    (((I band 16#7f) bor 16#80) bsl 24),
    <<I1:32>>;
    encode(I) when I >= 0 -> encode_long(I, <<>>).
    encode(I) when I >= 0 -> encode(I, <<>>).

    -spec encode_long(non_neg_integer(), binary()) -> binary().
    encode_long(I, Acc) when I =< 16#7f ->
    -spec encode(non_neg_integer(), binary()) -> binary().
    encode(I, Acc) when I =< 16#7f ->
    <<Acc/binary, I:8>>;
    encode_long(I, Acc) ->
    encode(I, Acc) ->
    I1 = (I bsr 7),
    Val = (I - (I1 bsl 7)) bor 16#80,
    encode_long(I1, <<Acc/binary, Val:8>>).
    encode(I1, <<Acc/binary, Val:8>>).

    -type decode_cont() :: {cont,
    non_neg_integer(),
  4. Hunter Morris revised this gist Aug 3, 2011. 1 changed file with 27 additions and 6 deletions.
    33 changes: 27 additions & 6 deletions uleb128.erl
    Original file line number Diff line number Diff line change
    @@ -7,6 +7,7 @@
    -include_lib("proper/include/proper.hrl").
    -export([prop_encode_decode/0]).

    -spec encode(non_neg_integer()) -> binary().
    encode(I) when I >= 0, I =< 16#7f -> <<I:8>>;
    encode(I) when I > 16#7f, I =< 16#3fff ->
    I1 = (((I band 16#7f) bor 16#80) bsl 8) bor ((I bsr 7) band 16#7f),
    @@ -24,13 +25,22 @@ encode(I) when I > 16#1fffff, I =< 16#fffffff ->
    <<I1:32>>;
    encode(I) when I >= 0 -> encode_long(I, <<>>).

    -spec encode_long(non_neg_integer(), binary()) -> binary().
    encode_long(I, Acc) when I =< 16#7f ->
    <<Acc/binary, I:8>>;
    encode_long(I, Acc) ->
    I1 = (I bsr 7),
    Val = (I - (I1 bsl 7)) bor 16#80,
    encode_long(I1, <<Acc/binary, Val:8>>).

    -type decode_cont() :: {cont,
    non_neg_integer(),
    non_neg_integer(),
    non_neg_integer()}.
    -type decode_ret() :: non_neg_integer()
    | {non_neg_integer(), binary()}
    | decode_cont().
    -spec decode(binary()) -> decode_ret().
    decode(<<0:1, A:7>>) -> A;
    decode(<<0:1, A:7, Rest/binary>>) -> {A, Rest};
    decode(<<1:1, A:7, 0:1, B:7>>) -> B bsl 7 bor A;
    @@ -50,9 +60,8 @@ decode(<<1:1, A:7, 1:1, B:7, 1:1, C:7, 1:1, D:7, _/binary>> = Bin) ->
    decode(Bin) ->
    decode(Bin, {cont, 0, 0, 0}).

    decode(Bin, {cont, Acc, X, Offset}) -> decode_long(Bin, {cont, Acc, X, Offset}).

    decode_long(Bin, {cont, Acc, X, Offset}) ->
    -spec decode(binary(), decode_cont()) -> decode_ret().
    decode(Bin, {cont, Acc, X, Offset}) ->
    case Bin of
    <<_:Offset/bytes, 0:1, I:7>> ->
    Acc bor (I bsl (X * 7));
    @@ -63,10 +72,10 @@ decode_long(Bin, {cont, Acc, X, Offset}) ->
    {cont, Acc bor (I bsl (X * 7)), X + 1, 0};
    <<_:Offset/bytes, 1:1, I:7, _/binary>> ->
    Acc1 = Acc bor (I bsl (X * 7)),
    decode_long(Bin, {cont, Acc1, X + 1, Offset + 1})
    decode(Bin, {cont, Acc1, X + 1, Offset + 1})
    end.

    large_pos_integer() ->
    large_non_neg_integer() ->
    union([integer(0, inf),
    integer(16#7f, inf),
    integer(16#3fff, inf),
    @@ -75,4 +84,16 @@ large_pos_integer() ->

    % Properties for testing
    prop_encode_decode() ->
    ?FORALL(I, large_pos_integer(), begin I =:= decode(encode(I)) end).
    ?FORALL(I, large_non_neg_integer(), begin I =:= decode(encode(I)) end).

    prop_encode_decode_long() ->
    ?FORALL(I, large_non_neg_integer(),
    begin
    Bin = encode(I),
    Cont = decode(<<(binary:at(Bin, 0))>>),
    I =:=
    lists:foldl(
    fun(X, Acc) ->
    decode(<<(binary:at(Bin, X))>>, Acc)
    end, Cont, lists:seq(1, byte_size(Bin) - 1))
    end).
  5. Hunter Morris revised this gist Aug 3, 2011. 1 changed file with 7 additions and 7 deletions.
    14 changes: 7 additions & 7 deletions uleb128.erl
    Original file line number Diff line number Diff line change
    @@ -22,14 +22,14 @@ encode(I) when I > 16#1fffff, I =< 16#fffffff ->
    ((((I bsr 7) band 16#7f) bor 16#80) bsl 16) bor
    (((I band 16#7f) bor 16#80) bsl 24),
    <<I1:32>>;
    encode(I) when I >= 0 -> encode_long_varint(I, <<>>).
    encode(I) when I >= 0 -> encode_long(I, <<>>).

    encode_long_varint(I, Acc) when I =< 16#7f ->
    encode_long(I, Acc) when I =< 16#7f ->
    <<Acc/binary, I:8>>;
    encode_long_varint(I, Acc) ->
    encode_long(I, Acc) ->
    I1 = (I bsr 7),
    Val = (I - (I1 bsl 7)) bor 16#80,
    encode_long_varint(I1, <<Acc/binary, Val:8>>).
    encode_long(I1, <<Acc/binary, Val:8>>).

    decode(<<0:1, A:7>>) -> A;
    decode(<<0:1, A:7, Rest/binary>>) -> {A, Rest};
    @@ -50,9 +50,9 @@ decode(<<1:1, A:7, 1:1, B:7, 1:1, C:7, 1:1, D:7, _/binary>> = Bin) ->
    decode(Bin) ->
    decode(Bin, {cont, 0, 0, 0}).

    decode(Bin, {cont, Acc, X, Offset}) -> decode_long_varint(Bin, {cont, Acc, X, Offset}).
    decode(Bin, {cont, Acc, X, Offset}) -> decode_long(Bin, {cont, Acc, X, Offset}).

    decode_long_varint(Bin, {cont, Acc, X, Offset}) ->
    decode_long(Bin, {cont, Acc, X, Offset}) ->
    case Bin of
    <<_:Offset/bytes, 0:1, I:7>> ->
    Acc bor (I bsl (X * 7));
    @@ -63,7 +63,7 @@ decode_long_varint(Bin, {cont, Acc, X, Offset}) ->
    {cont, Acc bor (I bsl (X * 7)), X + 1, 0};
    <<_:Offset/bytes, 1:1, I:7, _/binary>> ->
    Acc1 = Acc bor (I bsl (X * 7)),
    decode_long_varint(Bin, {cont, Acc1, X + 1, Offset + 1})
    decode_long(Bin, {cont, Acc1, X + 1, Offset + 1})
    end.

    large_pos_integer() ->
  6. Hunter Morris revised this gist Aug 3, 2011. 1 changed file with 15 additions and 13 deletions.
    28 changes: 15 additions & 13 deletions uleb128.erl
    Original file line number Diff line number Diff line change
    @@ -46,31 +46,33 @@ decode(<<1:1, A:7, 1:1, B:7, 1:1, C:7, 0:1, D:7, Rest/binary>>) ->
    {(D bsl 21) bor (C bsl 14) bor (B bsl 7) bor A, Rest};
    decode(<<1:1, A:7, 1:1, B:7, 1:1, C:7, 1:1, D:7, _/binary>> = Bin) ->
    Acc = (D bsl 21) bor (C bsl 14) bor (B bsl 7) bor A,
    decode_long_varint(Bin, Acc, 4, 4);
    decode(Bin) -> decode_long_varint(Bin, 0, 0, 0).
    decode(Bin, {cont, Acc, 4, 4});
    decode(Bin) ->
    decode(Bin, {cont, 0, 0, 0}).

    decode(Bin, {cont, Acc, X}) -> decode_long_varint(Bin, Acc, X, 0).
    decode(Bin, {cont, Acc, X, Offset}) -> decode_long_varint(Bin, {cont, Acc, X, Offset}).

    decode_long_varint(Bin, Acc, X, Offset) ->
    decode_long_varint(Bin, {cont, Acc, X, Offset}) ->
    case Bin of
    <<_:Offset/bytes, 0:1, I:7>> ->
    Acc bor (I bsl (X * 7));
    <<_:Offset/bytes, 0:1, I:7, Rest/binary>> ->
    Result = Acc bor (I bsl (X * 7)),
    {Result, Rest};
    <<_:Offset/bytes, 1:1, I:7>> ->
    {cont, Acc bor (I bsl (X * 7)), X + 1};
    {cont, Acc bor (I bsl (X * 7)), X + 1, 0};
    <<_:Offset/bytes, 1:1, I:7, _/binary>> ->
    Acc1 = Acc bor (I bsl (X * 7)),
    decode_long_varint(Bin, Acc1, Offset + 1, X + 1)
    decode_long_varint(Bin, {cont, Acc1, X + 1, Offset + 1})
    end.

    large_pos_integer() ->
    union([integer(0, inf),
    integer(16#7f, inf),
    integer(16#3fff, inf),
    integer(16#1fffff, inf),
    integer(16#fffffff, inf)]).

    % Properties for testing
    prop_encode_decode() ->
    ?FORALL(I,
    union([integer(0, inf),
    integer(16#7f, inf),
    integer(16#3fff, inf),
    integer(16#1fffff, inf),
    integer(16#fffffff, inf)]),
    begin I =:= decode(encode(I)) end).
    ?FORALL(I, large_pos_integer(), begin I =:= decode(encode(I)) end).
  7. Hunter Morris revised this gist Aug 3, 2011. 1 changed file with 1 addition and 7 deletions.
    8 changes: 1 addition & 7 deletions uleb128.erl
    Original file line number Diff line number Diff line change
    @@ -2,12 +2,11 @@
    -module(uleb128).

    -export([encode/1, decode/1, decode/2]).
    %-export([encode_front/1, decode_front/1, decode_front/2]).

    % For property tests
    -include_lib("proper/include/proper.hrl").
    -export([prop_encode_decode/0]).
    -compile(export_all).

    encode(I) when I >= 0, I =< 16#7f -> <<I:8>>;
    encode(I) when I > 16#7f, I =< 16#3fff ->
    I1 = (((I band 16#7f) bor 16#80) bsl 8) bor ((I bsr 7) band 16#7f),
    @@ -66,11 +65,6 @@ decode_long_varint(Bin, Acc, X, Offset) ->
    decode_long_varint(Bin, Acc1, Offset + 1, X + 1)
    end.

    % Exponentiation by squaring
    pow(X, N) -> pow(X, N, 1).
    pow(X, N, R) when N < 2 -> R * X;
    pow(X, N, R) -> pow(X * X, N bsr 1, case N band 1 of 1 -> R * X; 0 -> R end).

    % Properties for testing
    prop_encode_decode() ->
    ?FORALL(I,
  8. Hunter Morris revised this gist Aug 3, 2011. 1 changed file with 7 additions and 8 deletions.
    15 changes: 7 additions & 8 deletions uleb128.erl
    Original file line number Diff line number Diff line change
    @@ -2,11 +2,12 @@
    -module(uleb128).

    -export([encode/1, decode/1, decode/2]).
    %-export([encode_front/1, decode_front/1, decode_front/2]).

    % For property tests
    -include_lib("proper/include/proper.hrl").
    -export([prop_encode_decode/0]).

    -compile(export_all).
    encode(I) when I >= 0, I =< 16#7f -> <<I:8>>;
    encode(I) when I > 16#7f, I =< 16#3fff ->
    I1 = (((I band 16#7f) bor 16#80) bsl 8) bor ((I bsr 7) band 16#7f),
    @@ -65,14 +66,12 @@ decode_long_varint(Bin, Acc, X, Offset) ->
    decode_long_varint(Bin, Acc1, Offset + 1, X + 1)
    end.

    % ./uleb128.erl:35: Warning: NOT OPTIMIZED: sub binary is used or returned
    % ./uleb128.erl:37: Warning: NOT OPTIMIZED: sub binary is used or returned
    % ./uleb128.erl:41: Warning: NOT OPTIMIZED: sub binary is used or returned
    % ./uleb128.erl:45: Warning: NOT OPTIMIZED: sub binary is used or returned
    % ./uleb128.erl:47: Warning: INFO: the '=' operator will prevent delayed sub binary optimization
    % ./uleb128.erl:58: Warning: NOT OPTIMIZED: sub binary is used or returned
    % ./uleb128.erl:63: Warning: INFO: using a matched out sub binary will prevent delayed sub binary optimization
    % Exponentiation by squaring
    pow(X, N) -> pow(X, N, 1).
    pow(X, N, R) when N < 2 -> R * X;
    pow(X, N, R) -> pow(X * X, N bsr 1, case N band 1 of 1 -> R * X; 0 -> R end).

    % Properties for testing
    prop_encode_decode() ->
    ?FORALL(I,
    union([integer(0, inf),
  9. Hunter Morris revised this gist Aug 2, 2011. 1 changed file with 21 additions and 9 deletions.
    30 changes: 21 additions & 9 deletions uleb128.erl
    Original file line number Diff line number Diff line change
    @@ -3,6 +3,10 @@

    -export([encode/1, decode/1, decode/2]).

    % For property tests
    -include_lib("proper/include/proper.hrl").
    -export([prop_encode_decode/0]).

    encode(I) when I >= 0, I =< 16#7f -> <<I:8>>;
    encode(I) when I > 16#7f, I =< 16#3fff ->
    I1 = (((I band 16#7f) bor 16#80) bsl 8) bor ((I bsr 7) band 16#7f),
    @@ -42,7 +46,7 @@ decode(<<1:1, A:7, 1:1, B:7, 1:1, C:7, 0:1, D:7, Rest/binary>>) ->
    {(D bsl 21) bor (C bsl 14) bor (B bsl 7) bor A, Rest};
    decode(<<1:1, A:7, 1:1, B:7, 1:1, C:7, 1:1, D:7, _/binary>> = Bin) ->
    Acc = (D bsl 21) bor (C bsl 14) bor (B bsl 7) bor A,
    decode_long_varint(Bin, Acc, 4, 0);
    decode_long_varint(Bin, Acc, 4, 4);
    decode(Bin) -> decode_long_varint(Bin, 0, 0, 0).

    decode(Bin, {cont, Acc, X}) -> decode_long_varint(Bin, Acc, X, 0).
    @@ -61,11 +65,19 @@ decode_long_varint(Bin, Acc, X, Offset) ->
    decode_long_varint(Bin, Acc1, Offset + 1, X + 1)
    end.

    % $ erlc +bin_opt_info uleb128.erl
    % ./uleb128.erl:32: Warning: NOT OPTIMIZED: sub binary is used or returned
    % ./uleb128.erl:34: Warning: NOT OPTIMIZED: sub binary is used or returned
    % ./uleb128.erl:38: Warning: NOT OPTIMIZED: sub binary is used or returned
    % ./uleb128.erl:42: Warning: NOT OPTIMIZED: sub binary is used or returned
    % ./uleb128.erl:44: Warning: INFO: the '=' operator will prevent delayed sub binary optimization
    % ./uleb128.erl:55: Warning: NOT OPTIMIZED: sub binary is used or returned
    % ./uleb128.erl:60: Warning: INFO: using a matched out sub binary will prevent delayed sub binary optimization
    % ./uleb128.erl:35: Warning: NOT OPTIMIZED: sub binary is used or returned
    % ./uleb128.erl:37: Warning: NOT OPTIMIZED: sub binary is used or returned
    % ./uleb128.erl:41: Warning: NOT OPTIMIZED: sub binary is used or returned
    % ./uleb128.erl:45: Warning: NOT OPTIMIZED: sub binary is used or returned
    % ./uleb128.erl:47: Warning: INFO: the '=' operator will prevent delayed sub binary optimization
    % ./uleb128.erl:58: Warning: NOT OPTIMIZED: sub binary is used or returned
    % ./uleb128.erl:63: Warning: INFO: using a matched out sub binary will prevent delayed sub binary optimization

    prop_encode_decode() ->
    ?FORALL(I,
    union([integer(0, inf),
    integer(16#7f, inf),
    integer(16#3fff, inf),
    integer(16#1fffff, inf),
    integer(16#fffffff, inf)]),
    begin I =:= decode(encode(I)) end).
  10. Hunter Morris revised this gist Aug 2, 2011. 1 changed file with 20 additions and 16 deletions.
    36 changes: 20 additions & 16 deletions uleb128.erl
    Original file line number Diff line number Diff line change
    @@ -1,7 +1,7 @@

    -module(uleb128).

    -export([encode/1, decode/1]).
    -export([encode/1, decode/1, decode/2]).

    encode(I) when I >= 0, I =< 16#7f -> <<I:8>>;
    encode(I) when I > 16#7f, I =< 16#3fff ->
    @@ -42,26 +42,30 @@ decode(<<1:1, A:7, 1:1, B:7, 1:1, C:7, 0:1, D:7, Rest/binary>>) ->
    {(D bsl 21) bor (C bsl 14) bor (B bsl 7) bor A, Rest};
    decode(<<1:1, A:7, 1:1, B:7, 1:1, C:7, 1:1, D:7, _/binary>> = Bin) ->
    Acc = (D bsl 21) bor (C bsl 14) bor (B bsl 7) bor A,
    decode_long_varint(Bin, Acc, 4).
    decode_long_varint(Bin, Acc, 4, 0);
    decode(Bin) -> decode_long_varint(Bin, 0, 0, 0).

    decode_long_varint(Bin, Acc, X) ->
    decode(Bin, {cont, Acc, X}) -> decode_long_varint(Bin, Acc, X, 0).

    decode_long_varint(Bin, Acc, X, Offset) ->
    case Bin of
    <<_:X/bytes, 0:1, I:7, Rest/binary>> ->
    <<_:Offset/bytes, 0:1, I:7>> ->
    Acc bor (I bsl (X * 7));
    <<_:Offset/bytes, 0:1, I:7, Rest/binary>> ->
    Result = Acc bor (I bsl (X * 7)),
    {Result, Rest};
    <<_:X/bytes, 0:1, I:7>> ->
    Acc bor (I bsl (X * 7));
    <<_:X/bytes, 1:1, I:7, _/binary>> ->
    <<_:Offset/bytes, 1:1, I:7>> ->
    {cont, Acc bor (I bsl (X * 7)), X + 1};
    <<_:Offset/bytes, 1:1, I:7, _/binary>> ->
    Acc1 = Acc bor (I bsl (X * 7)),
    decode_long_varint(Bin, Acc1, X + 1);
    _ -> exit(varint_too_short)
    decode_long_varint(Bin, Acc1, Offset + 1, X + 1)
    end.

    % $ erlc +bin_opt_info uleb128.erl
    % ./uleb128.erl:31: Warning: NOT OPTIMIZED: sub binary is used or returned
    % ./uleb128.erl:33: Warning: NOT OPTIMIZED: sub binary is used or returned
    % ./uleb128.erl:37: Warning: NOT OPTIMIZED: sub binary is used or returned
    % ./uleb128.erl:41: Warning: NOT OPTIMIZED: sub binary is used or returned
    % ./uleb128.erl:43: Warning: INFO: the '=' operator will prevent delayed sub binary optimization
    % ./uleb128.erl:49: Warning: NOT OPTIMIZED: sub binary is used or returned
    % ./uleb128.erl:54: Warning: INFO: using a matched out sub binary will prevent delayed sub binary optimization
    % ./uleb128.erl:32: Warning: NOT OPTIMIZED: sub binary is used or returned
    % ./uleb128.erl:34: Warning: NOT OPTIMIZED: sub binary is used or returned
    % ./uleb128.erl:38: Warning: NOT OPTIMIZED: sub binary is used or returned
    % ./uleb128.erl:42: Warning: NOT OPTIMIZED: sub binary is used or returned
    % ./uleb128.erl:44: Warning: INFO: the '=' operator will prevent delayed sub binary optimization
    % ./uleb128.erl:55: Warning: NOT OPTIMIZED: sub binary is used or returned
    % ./uleb128.erl:60: Warning: INFO: using a matched out sub binary will prevent delayed sub binary optimization
  11. Hunter Morris revised this gist Aug 2, 2011. 1 changed file with 16 additions and 4 deletions.
    20 changes: 16 additions & 4 deletions uleb128.erl
    Original file line number Diff line number Diff line change
    @@ -28,20 +28,27 @@ encode_long_varint(I, Acc) ->
    encode_long_varint(I1, <<Acc/binary, Val:8>>).

    decode(<<0:1, A:7>>) -> A;
    decode(<<0:1, A:7, Rest/binary>>) -> {A, Rest};
    decode(<<1:1, A:7, 0:1, B:7>>) -> B bsl 7 bor A;
    decode(<<1:1, A:7, 0:1, B:7, Rest/binary>>) ->
    {B bsl 7 bor A, Rest};
    decode(<<1:1, A:7, 1:1, B:7, 0:1, C:7>>) ->
    (C bsl 14) bor (B bsl 7) bor A;
    decode(<<1:1, A:7, 1:1, B:7, 0:1, C:7, Rest/binary>>) ->
    {(C bsl 14) bor (B bsl 7) bor A, Rest};
    decode(<<1:1, A:7, 1:1, B:7, 1:1, C:7, 0:1, D:7>>) ->
    (D bsl 21) bor (C bsl 14) bor (B bsl 7) bor A;
    decode(<<1:1, A:7, 1:1, B:7, 1:1, C:7, 0:1, D:7, Rest/binary>>) ->
    {(D bsl 21) bor (C bsl 14) bor (B bsl 7) bor A, Rest};
    decode(<<1:1, A:7, 1:1, B:7, 1:1, C:7, 1:1, D:7, _/binary>> = Bin) ->
    Acc = (D bsl 21) bor (C bsl 14) bor (B bsl 7) bor A,
    decode_long_varint(Bin, Acc, 4).

    decode_long_varint(Bin, Acc, X) ->
    case Bin of
    <<_:X/bytes, 0:1, I:7, _/binary>> ->
    <<_:X/bytes, 0:1, I:7, Rest/binary>> ->
    Result = Acc bor (I bsl (X * 7)),
    {Result, X + 1};
    {Result, Rest};
    <<_:X/bytes, 0:1, I:7>> ->
    Acc bor (I bsl (X * 7));
    <<_:X/bytes, 1:1, I:7, _/binary>> ->
    @@ -51,5 +58,10 @@ decode_long_varint(Bin, Acc, X) ->
    end.

    % $ erlc +bin_opt_info uleb128.erl
    % ./uleb128.erl:35: Warning: INFO: the '=' operator will prevent delayed sub binary optimization
    % ./uleb128.erl:46: Warning: INFO: using a matched out sub binary will prevent delayed sub binary optimization
    % ./uleb128.erl:31: Warning: NOT OPTIMIZED: sub binary is used or returned
    % ./uleb128.erl:33: Warning: NOT OPTIMIZED: sub binary is used or returned
    % ./uleb128.erl:37: Warning: NOT OPTIMIZED: sub binary is used or returned
    % ./uleb128.erl:41: Warning: NOT OPTIMIZED: sub binary is used or returned
    % ./uleb128.erl:43: Warning: INFO: the '=' operator will prevent delayed sub binary optimization
    % ./uleb128.erl:49: Warning: NOT OPTIMIZED: sub binary is used or returned
    % ./uleb128.erl:54: Warning: INFO: using a matched out sub binary will prevent delayed sub binary optimization
  12. hntrmrrs renamed this gist Aug 2, 2011. 1 changed file with 19 additions and 18 deletions.
    37 changes: 19 additions & 18 deletions gistfile1.erl → uleb128.erl
    Original file line number Diff line number Diff line change
    @@ -1,6 +1,7 @@

    -module(uleb128).

    -export([encode/1]).
    -export([encode/1, decode/1]).

    encode(I) when I >= 0, I =< 16#7f -> <<I:8>>;
    encode(I) when I > 16#7f, I =< 16#3fff ->
    @@ -32,23 +33,23 @@ decode(<<1:1, A:7, 1:1, B:7, 0:1, C:7>>) ->
    (C bsl 14) bor (B bsl 7) bor A;
    decode(<<1:1, A:7, 1:1, B:7, 1:1, C:7, 0:1, D:7>>) ->
    (D bsl 21) bor (C bsl 14) bor (B bsl 7) bor A;
    decode(<<1:1, A:7, 1:1, B:7, 1:1, C:7, 1:1, D:7, Rest/binary>>) ->
    decode(<<1:1, A:7, 1:1, B:7, 1:1, C:7, 1:1, D:7, _/binary>> = Bin) ->
    Acc = (D bsl 21) bor (C bsl 14) bor (B bsl 7) bor A,
    decode_long_varint(Rest, Acc, 28).
    decode_long_varint(Bin, Acc, 4).

    decode_long_varint(<<0:1, I:7, Rest/binary>>, Acc, X) ->
    Result = Acc bor (I bsl X),
    case Rest of
    <<>> -> Result;
    _ -> {Result, Rest}
    end;
    decode_long_varint(<<1:1, I:7, Rest/binary>>, Acc, X) ->
    Acc1 = Acc bor (I bsl X),
    decode_long_varint(Rest, Acc1, X + 7);
    decode_long_varint(_Bin, _Acc, _X) ->
    exit(varint_too_short).
    decode_long_varint(Bin, Acc, X) ->
    case Bin of
    <<_:X/bytes, 0:1, I:7, _/binary>> ->
    Result = Acc bor (I bsl (X * 7)),
    {Result, X + 1};
    <<_:X/bytes, 0:1, I:7>> ->
    Acc bor (I bsl (X * 7));
    <<_:X/bytes, 1:1, I:7, _/binary>> ->
    Acc1 = Acc bor (I bsl (X * 7)),
    decode_long_varint(Bin, Acc1, X + 1);
    _ -> exit(varint_too_short)
    end.

    %% $ erlc +bin_opt_info varint.erl
    %% ./uleb128.erl:35: Warning: OPTIMIZED: creation of sub binary delayed
    %% ./uleb128.erl:39: Warning: NOT OPTIMIZED: sub binary is used or returned
    %% ./uleb128.erl:45: Warning: OPTIMIZED: creation of sub binary delayed
    % $ erlc +bin_opt_info uleb128.erl
    % ./uleb128.erl:35: Warning: INFO: the '=' operator will prevent delayed sub binary optimization
    % ./uleb128.erl:46: Warning: INFO: using a matched out sub binary will prevent delayed sub binary optimization
  13. hntrmrrs revised this gist Aug 2, 2011. 1 changed file with 5 additions and 0 deletions.
    5 changes: 5 additions & 0 deletions gistfile1.erl
    Original file line number Diff line number Diff line change
    @@ -47,3 +47,8 @@ decode_long_varint(<<1:1, I:7, Rest/binary>>, Acc, X) ->
    decode_long_varint(Rest, Acc1, X + 7);
    decode_long_varint(_Bin, _Acc, _X) ->
    exit(varint_too_short).

    %% $ erlc +bin_opt_info varint.erl
    %% ./uleb128.erl:35: Warning: OPTIMIZED: creation of sub binary delayed
    %% ./uleb128.erl:39: Warning: NOT OPTIMIZED: sub binary is used or returned
    %% ./uleb128.erl:45: Warning: OPTIMIZED: creation of sub binary delayed
  14. hntrmrrs revised this gist Aug 2, 2011. 1 changed file with 23 additions and 1 deletion.
    24 changes: 23 additions & 1 deletion gistfile1.erl
    Original file line number Diff line number Diff line change
    @@ -2,7 +2,7 @@

    -export([encode/1]).

    encode(I) when I >= 0, I =< 16#7f -> binary:encode_unsigned(I);
    encode(I) when I >= 0, I =< 16#7f -> <<I:8>>;
    encode(I) when I > 16#7f, I =< 16#3fff ->
    I1 = (((I band 16#7f) bor 16#80) bsl 8) bor ((I bsr 7) band 16#7f),
    <<I1:16>>;
    @@ -25,3 +25,25 @@ encode_long_varint(I, Acc) ->
    I1 = (I bsr 7),
    Val = (I - (I1 bsl 7)) bor 16#80,
    encode_long_varint(I1, <<Acc/binary, Val:8>>).

    decode(<<0:1, A:7>>) -> A;
    decode(<<1:1, A:7, 0:1, B:7>>) -> B bsl 7 bor A;
    decode(<<1:1, A:7, 1:1, B:7, 0:1, C:7>>) ->
    (C bsl 14) bor (B bsl 7) bor A;
    decode(<<1:1, A:7, 1:1, B:7, 1:1, C:7, 0:1, D:7>>) ->
    (D bsl 21) bor (C bsl 14) bor (B bsl 7) bor A;
    decode(<<1:1, A:7, 1:1, B:7, 1:1, C:7, 1:1, D:7, Rest/binary>>) ->
    Acc = (D bsl 21) bor (C bsl 14) bor (B bsl 7) bor A,
    decode_long_varint(Rest, Acc, 28).

    decode_long_varint(<<0:1, I:7, Rest/binary>>, Acc, X) ->
    Result = Acc bor (I bsl X),
    case Rest of
    <<>> -> Result;
    _ -> {Result, Rest}
    end;
    decode_long_varint(<<1:1, I:7, Rest/binary>>, Acc, X) ->
    Acc1 = Acc bor (I bsl X),
    decode_long_varint(Rest, Acc1, X + 7);
    decode_long_varint(_Bin, _Acc, _X) ->
    exit(varint_too_short).
  15. hntrmrrs created this gist Aug 2, 2011.
    27 changes: 27 additions & 0 deletions gistfile1.erl
    Original file line number Diff line number Diff line change
    @@ -0,0 +1,27 @@
    -module(uleb128).

    -export([encode/1]).

    encode(I) when I >= 0, I =< 16#7f -> binary:encode_unsigned(I);
    encode(I) when I > 16#7f, I =< 16#3fff ->
    I1 = (((I band 16#7f) bor 16#80) bsl 8) bor ((I bsr 7) band 16#7f),
    <<I1:16>>;
    encode(I) when I > 16#3fff, I =< 16#1fffff ->
    I1 = ((I bsr 14) band 16#7f) bor
    ((((I bsr 7) band 16#7f) bor 16#80) bsl 8) bor
    (((I band 16#7f) bor 16#80) bsl 16),
    <<I1:24>>;
    encode(I) when I > 16#1fffff, I =< 16#fffffff ->
    I1 = ((I bsr 21) band 16#7f) bor
    ((((I bsr 14) band 16#7f) bor 16#80) bsl 8) bor
    ((((I bsr 7) band 16#7f) bor 16#80) bsl 16) bor
    (((I band 16#7f) bor 16#80) bsl 24),
    <<I1:32>>;
    encode(I) when I >= 0 -> encode_long_varint(I, <<>>).

    encode_long_varint(I, Acc) when I =< 16#7f ->
    <<Acc/binary, I:8>>;
    encode_long_varint(I, Acc) ->
    I1 = (I bsr 7),
    Val = (I - (I1 bsl 7)) bor 16#80,
    encode_long_varint(I1, <<Acc/binary, Val:8>>).