Packages
protox
2.0.8
2.0.9
2.0.8
2.0.7
2.0.6
2.0.5
2.0.4
2.0.3
2.0.2
2.0.1
2.0.0
2.0.0-dev
1.7.8
1.7.7
1.7.6
1.7.5
1.7.4
retired
1.7.3
1.7.2
1.7.1
1.7.0
1.6.10
1.6.9
1.6.8
1.6.7
1.6.6
1.6.5
1.6.4
1.6.3
1.6.2
1.6.1
1.6.0
1.5.1
1.5.0
1.4.0
1.3.2
1.3.1
1.3.0
1.2.4
1.2.3
1.2.2
1.2.1
1.2.0
1.1.1
1.1.0
1.0.0
0.25.0
0.24.0
0.23.1
0.23.0
0.22.0
0.21.0
0.20.0
0.19.1
0.19.0
0.18.0
0.17.0
0.16.2
0.16.1
0.16.0
0.15.2
0.15.1
0.15.0
0.14.0
0.13.0
0.12.1
0.12.0
0.11.1
0.11.0
0.10.0
0.9.1
0.9.0
0.8.0
0.7.1
0.7.0
A fast, easy to use and 100% conformant Elixir library for Google Protocol Buffers (aka protobuf)
Current section
Files
Jump to
Current section
Files
lib/protox/varint.ex
defmodule Protox.Varint do
@moduledoc false
# Internal. Implement LEB128 compression.
import Bitwise
@spec encode(integer) :: {binary(), non_neg_integer()}
def encode(v) when v < 1 <<< 7, do: {<<v>>, 1}
def encode(v) when v < 1 <<< 14, do: {<<1::1, v::7, v >>> 7>>, 2}
def encode(v) when v < 1 <<< 21, do: {<<1::1, v::7, 1::1, v >>> 7::7, v >>> 14>>, 3}
def encode(v) when v < 1 <<< 28, do: {<<1::1, v::7, 1::1, v >>> 7::7, 1::1, v >>> 14::7, v >>> 21>>, 4}
def encode(v) when v < 1 <<< 35,
do: {<<1::1, v::7, 1::1, v >>> 7::7, 1::1, v >>> 14::7, 1::1, v >>> 21::7, v >>> 28>>, 5}
def encode(v) when v < 1 <<< 42,
do: {<<1::1, v::7, 1::1, v >>> 7::7, 1::1, v >>> 14::7, 1::1, v >>> 21::7, 1::1, v >>> 28::7, v >>> 35>>, 6}
def encode(v) when v < 1 <<< 49,
do:
{<<1::1, v::7, 1::1, v >>> 7::7, 1::1, v >>> 14::7, 1::1, v >>> 21::7, 1::1, v >>> 28::7, 1::1, v >>> 35::7,
v >>> 42>>, 7}
def encode(v) when v < 1 <<< 56,
do:
{<<1::1, v::7, 1::1, v >>> 7::7, 1::1, v >>> 14::7, 1::1, v >>> 21::7, 1::1, v >>> 28::7, 1::1, v >>> 35::7, 1::1,
v >>> 42::7, v >>> 49>>, 8}
def encode(v) do
{next_bytes, size} = encode(v >>> 7)
{<<1::1, v::7, next_bytes::binary>>, size + 1}
end
@spec decode(binary) :: {non_neg_integer, binary}
def decode(<<0::1, byte0::7, rest::binary>>), do: {byte0, rest}
def decode(<<1::1, byte1::7, 0::1, byte0::7, rest::binary>>), do: {byte1 <<< 0 ||| byte0 <<< 7, rest}
def decode(<<1::1, byte2::7, 1::1, byte1::7, 0::1, byte0::7, rest::binary>>),
do: {byte2 <<< 0 ||| byte1 <<< 7 ||| byte0 <<< 14, rest}
def decode(<<1::1, byte3::7, 1::1, byte2::7, 1::1, byte1::7, 0::1, byte0::7, rest::binary>>),
do: {byte3 <<< 0 ||| byte2 <<< 7 ||| byte1 <<< 14 ||| byte0 <<< 21, rest}
def decode(<<1::1, byte4::7, 1::1, byte3::7, 1::1, byte2::7, 1::1, byte1::7, 0::1, byte0::7, rest::binary>>),
do: {byte4 <<< 0 ||| byte3 <<< 7 ||| byte2 <<< 14 ||| byte1 <<< 21 ||| byte0 <<< 28, rest}
def decode(
<<1::1, byte5::7, 1::1, byte4::7, 1::1, byte3::7, 1::1, byte2::7, 1::1, byte1::7, 0::1, byte0::7, rest::binary>>
) do
{byte5 <<< 0 ||| byte4 <<< 7 ||| byte3 <<< 14 ||| byte2 <<< 21 ||| byte1 <<< 28 ||| byte0 <<< 35, rest}
end
def decode(
<<1::1, byte6::7, 1::1, byte5::7, 1::1, byte4::7, 1::1, byte3::7, 1::1, byte2::7, 1::1, byte1::7, 0::1,
byte0::7, rest::binary>>
),
do:
{byte6 <<< 0 ||| byte5 <<< 7 ||| byte4 <<< 14 ||| byte3 <<< 21 ||| byte2 <<< 28 ||| byte1 <<< 35 |||
byte0 <<< 42, rest}
def decode(
<<1::1, byte7::7, 1::1, byte6::7, 1::1, byte5::7, 1::1, byte4::7, 1::1, byte3::7, 1::1, byte2::7, 1::1,
byte1::7, 0::1, byte0::7, rest::binary>>
),
do:
{byte7 <<< 0 ||| byte6 <<< 7 ||| byte5 <<< 14 ||| byte4 <<< 21 ||| byte3 <<< 28 ||| byte2 <<< 35 |||
byte1 <<< 42 ||| byte0 <<< 49, rest}
def decode(b), do: do_decode(0, 0, b)
# -- Private
@spec do_decode(non_neg_integer, non_neg_integer, binary) :: {non_neg_integer, binary}
defp do_decode(result, shift, <<0::1, byte::7, rest::binary>>) do
{result ||| byte <<< shift, rest}
end
defp do_decode(result, shift, <<1::1, byte::7, rest::binary>>) do
do_decode(result ||| byte <<< shift, shift + 7, rest)
end
defp do_decode(_result, _shift, bytes) do
raise Protox.DecodingError.new(bytes, "invalid varint")
end
end