Packages
protox
1.7.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/encode.ex
defmodule Protox.Encode do
@moduledoc """
This module contains the functions necessary to encode protobuf messages.
"""
import Protox.Guards
import Bitwise
use Protox.{
Float,
WireTypes
}
alias Protox.{
Varint,
Zigzag
}
@doc """
Encode a protobuf message into IO data.
## Example
msg = %Fiz.Foo{a: 3, b: %{1 => %Fiz.Baz{}}}
{:ok, iodata} = Protox.Encode.encode(msg)
"""
@deprecated "Use Protox.encode/1 instead"
@spec encode(struct()) :: {:ok, iodata()} | {:error, any()}
def encode(msg) do
# A compilation error at the line below usually happen if `msg`
# is not a struct generated by protox.
msg.__struct__.encode(msg)
end
@doc """
Throwing version of `encode/1`.
"""
@deprecated "Use Protox.encode!/1 instead"
@spec encode!(struct()) :: iodata() | no_return()
def encode!(msg) do
# A compilation error at the line below usually happen if `msg`
# is not a struct generated by protox.
msg.__struct__.encode!(msg)
end
@doc false
@spec make_key_bytes(Protox.Types.tag(), Protox.Types.type()) :: iodata
def make_key_bytes(tag, ty) do
Varint.encode(make_key(tag, ty))
end
@doc false
@spec make_key(Protox.Types.tag(), Protox.Types.type()) :: non_neg_integer
def make_key(tag, ty) when is_primitive_varint(ty), do: tag <<< 3 ||| @wire_varint
def make_key(tag, {:enum, _}), do: tag <<< 3 ||| @wire_varint
def make_key(tag, ty) when is_primitive_fixed64(ty), do: tag <<< 3 ||| @wire_64bits
def make_key(tag, ty) when is_delimited(ty), do: tag <<< 3 ||| @wire_delimited
def make_key(tag, {:message, _}), do: tag <<< 3 ||| @wire_delimited
def make_key(tag, :packed), do: tag <<< 3 ||| @wire_delimited
def make_key(tag, :map_entry), do: tag <<< 3 ||| @wire_delimited
def make_key(tag, ty) when is_primitive_fixed32(ty), do: tag <<< 3 ||| @wire_32bits
@doc false
@spec encode_varint_signed(integer) :: iodata
def encode_varint_signed(value) do
value |> Zigzag.encode() |> Varint.encode()
end
@doc false
@spec encode_varint_64(integer) :: iodata
def encode_varint_64(value) do
<<res::unsigned-native-64>> = <<value::signed-native-64>>
Varint.encode(res)
end
@doc false
@spec encode_varint_32(integer) :: iodata
def encode_varint_32(value) when value < 0 do
encode_varint_64(value)
end
@doc false
def encode_varint_32(value) do
<<res::unsigned-native-32>> = <<value::signed-native-32>>
Varint.encode(res)
end
@doc false
@spec encode_bool(boolean) :: binary
def encode_bool(false), do: <<0>>
def encode_bool(true), do: <<1>>
@doc false
@spec encode_int32(integer) :: iodata
def encode_int32(value), do: encode_varint_32(value)
@doc false
@spec encode_int64(integer) :: iodata
def encode_int64(value), do: encode_varint_64(value)
@doc false
@spec encode_sint32(integer) :: iodata
def encode_sint32(value), do: encode_varint_signed(value)
@doc false
@spec encode_sint64(integer) :: iodata
def encode_sint64(value), do: encode_varint_signed(value)
@doc false
@spec encode_uint32(non_neg_integer) :: iodata
def encode_uint32(value), do: encode_varint_32(value)
@doc false
@spec encode_uint64(non_neg_integer) :: iodata
def encode_uint64(value), do: encode_varint_64(value)
@doc false
@spec encode_fixed64(integer) :: binary
def encode_fixed64(value), do: <<value::little-64>>
@doc false
@spec encode_sfixed64(integer) :: binary
def encode_sfixed64(value), do: <<value::signed-little-64>>
@doc false
@spec encode_fixed32(integer) :: binary
def encode_fixed32(value), do: <<value::little-32>>
@doc false
@spec encode_sfixed32(integer) :: binary
def encode_sfixed32(value), do: <<value::signed-little-32>>
@doc false
@spec encode_double(float | atom) :: binary
def encode_double(:infinity), do: @positive_infinity_64
def encode_double(:"-infinity"), do: @negative_infinity_64
def encode_double(:nan), do: @nan_64
def encode_double(value), do: <<value::float-little-64>>
@doc false
@spec encode_float(float | atom) :: binary
def encode_float(:infinity), do: @positive_infinity_32
def encode_float(:"-infinity"), do: @negative_infinity_32
def encode_float(:nan), do: @nan_32
def encode_float(value), do: <<value::float-little-32>>
@doc false
@spec encode_enum(integer) :: iodata
def encode_enum(value), do: encode_varint_32(value)
@doc false
@spec encode_string(String.t()) :: iodata
def encode_string(value) do
[Varint.encode(byte_size(value)), value]
end
@doc false
@spec encode_bytes(binary) :: iodata
def encode_bytes(value) do
[Varint.encode(byte_size(value)), value]
end
@doc false
@spec encode_message(struct) :: iodata
def encode_message(value) do
encoded = value |> encode!() |> :binary.list_to_bin()
[Varint.encode(byte_size(encoded)), encoded]
end
end