Packages
protox
1.1.1
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/decode.ex
defmodule Protox.Decode do
@moduledoc false
# Decodes a binary into a message.
use Bitwise
use Protox.{
Float,
WireTypes
}
alias Protox.{
Varint,
Zigzag
}
@compile {:inline,
parse_bool: 1,
parse_sint32: 1,
parse_sint64: 1,
parse_uint32: 1,
parse_uint64: 1,
parse_enum: 2,
parse_int32: 1,
parse_int64: 1,
parse_double: 1,
parse_float: 1,
parse_fixed32: 1,
parse_sfixed32: 1,
parse_fixed64: 1,
parse_sfixed64: 1}
# Get the key's tag and wire type.
@spec parse_key(binary) :: {non_neg_integer, non_neg_integer, binary}
def parse_key(bytes) do
{key, rest} = Varint.decode(bytes)
{key >>> 3, key &&& 0b111, rest}
end
def parse_unknown(tag, @wire_varint, bytes) do
{unknown_bytes, rest} = get_unknown_varint_bytes(<<>>, bytes)
{{tag, @wire_varint, unknown_bytes}, rest}
end
def parse_unknown(tag, @wire_64bits, <<unknown_bytes::64, rest::binary>>) do
{{tag, @wire_64bits, <<unknown_bytes::64>>}, rest}
end
def parse_unknown(tag, @wire_delimited, bytes) do
{len, new_bytes} = Varint.decode(bytes)
<<unknown_bytes::binary-size(len), rest::binary>> = new_bytes
{{tag, @wire_delimited, unknown_bytes}, rest}
end
def parse_unknown(tag, @wire_32bits, <<unknown_bytes::32, rest::binary>>) do
{{tag, @wire_32bits, <<unknown_bytes::32>>}, rest}
end
defp get_unknown_varint_bytes(acc, <<0::1, b::7, rest::binary>>) do
{<<acc::binary, 0::1, b::7>>, rest}
end
defp get_unknown_varint_bytes(acc, <<1::1, b::7, rest::binary>>) do
get_unknown_varint_bytes(<<acc::binary, 1::1, b::7>>, rest)
end
def parse_double(<<@positive_infinity_64, rest::binary>>), do: {:infinity, rest}
def parse_double(<<@negative_infinity_64, rest::binary>>), do: {:"-infinity", rest}
def parse_double(<<_::48, 0b1111::4, _::4, _::1, 0b1111111::7, rest::binary>>), do: {:nan, rest}
def parse_double(<<value::float-little-64, rest::binary>>), do: {value, rest}
def parse_float(<<@positive_infinity_32, rest::binary>>), do: {:infinity, rest}
def parse_float(<<@negative_infinity_32, rest::binary>>), do: {:"-infinity", rest}
def parse_float(<<_::16, 1::1, _::7, _::1, 0b1111111::7, rest::binary>>), do: {:nan, rest}
def parse_float(<<value::float-little-32, rest::binary>>), do: {value, rest}
def parse_sfixed64(<<value::signed-little-64, rest::binary>>), do: {value, rest}
def parse_fixed64(<<value::signed-little-64, rest::binary>>), do: {value, rest}
def parse_sfixed32(<<value::signed-little-32, rest::binary>>), do: {value, rest}
def parse_fixed32(<<value::signed-little-32, rest::binary>>), do: {value, rest}
def parse_bool(bytes) do
{value, rest} = Varint.decode(bytes)
{value != 0, rest}
end
def parse_sint32(bytes) do
{value, rest} = Varint.decode(bytes)
<<res::unsigned-native-32>> = <<value::unsigned-native-32>>
{Zigzag.decode(res), rest}
end
def parse_sint64(bytes) do
{value, rest} = Varint.decode(bytes)
<<res::unsigned-native-64>> = <<value::unsigned-native-64>>
{Zigzag.decode(res), rest}
end
def parse_uint32(bytes) do
{value, rest} = Varint.decode(bytes)
<<res::unsigned-native-32>> = <<value::unsigned-native-32>>
{res, rest}
end
def parse_uint64(bytes) do
{value, rest} = Varint.decode(bytes)
<<res::unsigned-native-64>> = <<value::unsigned-native-64>>
{res, rest}
end
def parse_enum(bytes, mod) do
{value, rest} = Varint.decode(bytes)
<<res::signed-native-32>> = <<value::signed-native-32>>
{mod.decode(res), rest}
end
def parse_int32(bytes) do
{value, rest} = Varint.decode(bytes)
<<res::signed-native-32>> = <<value::signed-native-32>>
{res, rest}
end
def parse_int64(bytes) do
{value, rest} = Varint.decode(bytes)
<<res::signed-native-64>> = <<value::signed-native-64>>
{res, rest}
end
def parse_repeated_bool(acc, <<>>), do: Enum.reverse(acc)
def parse_repeated_bool(acc, bytes) do
{value, rest} = Protox.Varint.decode(bytes)
parse_repeated_bool([value != 0 | acc], rest)
end
def parse_repeated_enum(acc, <<>>, _mod), do: Enum.reverse(acc)
def parse_repeated_enum(acc, bytes, mod) do
{value, rest} = parse_enum(bytes, mod)
parse_repeated_enum([value | acc], rest, mod)
end
def parse_repeated_int32(acc, <<>>), do: Enum.reverse(acc)
def parse_repeated_int32(acc, bytes) do
{value, rest} = parse_int32(bytes)
parse_repeated_int32([value | acc], rest)
end
def parse_repeated_uint32(acc, <<>>), do: Enum.reverse(acc)
def parse_repeated_uint32(acc, bytes) do
{value, rest} = parse_uint32(bytes)
parse_repeated_uint32([value | acc], rest)
end
def parse_repeated_sint32(acc, <<>>), do: Enum.reverse(acc)
def parse_repeated_sint32(acc, bytes) do
{value, rest} = parse_sint32(bytes)
parse_repeated_sint32([value | acc], rest)
end
def parse_repeated_int64(acc, <<>>), do: Enum.reverse(acc)
def parse_repeated_int64(acc, bytes) do
{value, rest} = parse_int64(bytes)
parse_repeated_int64([value | acc], rest)
end
def parse_repeated_uint64(acc, <<>>), do: Enum.reverse(acc)
def parse_repeated_uint64(acc, bytes) do
{value, rest} = parse_uint64(bytes)
parse_repeated_uint64([value | acc], rest)
end
def parse_repeated_sint64(acc, <<>>), do: Enum.reverse(acc)
def parse_repeated_sint64(acc, bytes) do
{value, rest} = parse_sint64(bytes)
parse_repeated_sint64([value | acc], rest)
end
def parse_repeated_fixed32(acc, <<>>), do: Enum.reverse(acc)
def parse_repeated_fixed32(acc, bytes) do
{value, rest} = parse_fixed32(bytes)
parse_repeated_fixed32([value | acc], rest)
end
def parse_repeated_fixed64(acc, <<>>), do: Enum.reverse(acc)
def parse_repeated_fixed64(acc, bytes) do
{value, rest} = parse_fixed64(bytes)
parse_repeated_fixed64([value | acc], rest)
end
def parse_repeated_sfixed32(acc, <<>>), do: Enum.reverse(acc)
def parse_repeated_sfixed32(acc, bytes) do
{value, rest} = parse_sfixed32(bytes)
parse_repeated_sfixed32([value | acc], rest)
end
def parse_repeated_sfixed64(acc, <<>>), do: Enum.reverse(acc)
def parse_repeated_sfixed64(acc, bytes) do
{value, rest} = parse_sfixed64(bytes)
parse_repeated_sfixed64([value | acc], rest)
end
def parse_repeated_float(acc, <<>>), do: Enum.reverse(acc)
def parse_repeated_float(acc, bytes) do
{value, rest} = parse_float(bytes)
parse_repeated_float([value | acc], rest)
end
def parse_repeated_double(acc, <<>>), do: Enum.reverse(acc)
def parse_repeated_double(acc, bytes) do
{value, rest} = parse_double(bytes)
parse_repeated_double([value | acc], rest)
end
end