Packages
protox
1.6.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/decode.ex
defmodule Protox.Decode do
@moduledoc false
# Helpers decoding functions that will be used by the generated code.
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)
try do
<<unknown_bytes::binary-size(len), rest::binary>> = new_bytes
{{tag, @wire_delimited, unknown_bytes}, rest}
rescue
_ ->
reraise Protox.DecodingError.new(bytes, "invalid bytes for unknown delimited"),
__STACKTRACE__
end
end
def parse_unknown(tag, @wire_32bits, <<unknown_bytes::32, rest::binary>>) do
{{tag, @wire_32bits, <<unknown_bytes::32>>}, rest}
end
def parse_unknown(_tag, _wire_type, bin) do
raise Protox.DecodingError.new(bin, "can't parse unknown bytes")
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
defp get_unknown_varint_bytes(_acc, bin) do
raise Protox.DecodingError.new(bin, "can't parse unknown varint bytes")
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_double(bin), do: raise(Protox.DecodingError.new(bin, "invalid double"))
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_float(bin), do: raise(Protox.DecodingError.new(bin, "invalid float"))
def parse_sfixed64(<<value::signed-little-64, rest::binary>>), do: {value, rest}
def parse_sfixed64(bin), do: raise(Protox.DecodingError.new(bin, "invalid sfixed64"))
def parse_fixed64(<<value::unsigned-little-64, rest::binary>>), do: {value, rest}
def parse_fixed64(bin), do: raise(Protox.DecodingError.new(bin, "invalid fixed64"))
def parse_sfixed32(<<value::signed-little-32, rest::binary>>), do: {value, rest}
def parse_sfixed32(bin), do: raise(Protox.DecodingError.new(bin, "invalid sfixed32"))
def parse_fixed32(<<value::unsigned-little-32, rest::binary>>), do: {value, rest}
def parse_fixed32(bin), do: raise(Protox.DecodingError.new(bin, "invalid fixed32"))
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
def parse_delimited(bytes, len) do
try do
<<value::binary-size(len), rest::binary>> = bytes
{value, rest}
rescue
_ ->
reraise Protox.DecodingError.new(bytes, "invalid bytes for delimited field"),
__STACKTRACE__
end
end
end