Created
August 2, 2011 16:43
-
-
Save hntrmrrs/1120616 to your computer and use it in GitHub Desktop.
varint / ULEB128
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| -module(uleb128). | |
| -export([encode/1]). | |
| 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_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>>). | |
| 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). | |
| %% $ 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 |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment