Packages

This is a flatbuffers implementation in Elixir. In contrast to existing implementations there is no need to compile code from a schema. Instead, data and schemas are processed dynamically at runtime, offering greater flexibility.

Current section

Files

Jump to
eflatbuffers lib eflatbuffers.ex
Raw

lib/eflatbuffers.ex

defmodule Eflatbuffers do
def parse_schema(schema_str) do
Eflatbuffers.Schema.parse(schema_str)
end
def parse_schema!(schema_str) do
case parse_schema(schema_str) do
{:ok, schema} -> schema
error -> throw error
end
end
def write!(map, schema_str) when is_binary(schema_str) do
write!(map, parse_schema!(schema_str))
end
def write!(map, {_, %{root_type: root_type} = options} = schema) do
root_table = [<< vtable_offset :: little-size(16) >> | _] = Eflatbuffers.Writer.write({:table, %{ name: root_type }}, map, [], schema)
file_identifier =
case Map.get(options, :file_identifier) do
<< bin :: size(32) >> -> << bin :: size(32) >>
_ -> << 0, 0, 0, 0 >>
end
[<< (vtable_offset + 4 + byte_size(file_identifier)) :: little-size(32) >>, file_identifier, root_table]
|> :erlang.iolist_to_binary
end
def write(map, schema_str) when is_binary(schema_str) do
case parse_schema(schema_str) do
{:ok, schema} -> write(map, schema)
error -> error
end
end
def write(map, schema) do
try do
{:ok, write!(map, schema)}
catch
error -> error
rescue
error -> {:error, error}
end
end
def read!(data, schema_str) when is_binary(schema_str) do
read!(data, parse_schema!(schema_str))
end
def read!(data, {_, schema_options = %{root_type: root_type}} = schema) do
match_identifiers(data, schema_options)
Eflatbuffers.Reader.read({:table, %{ name: root_type }}, 0, data, schema)
end
def match_identifiers( << _::size(4)-binary, identifier_data::size(4)-binary, _::binary >>, schema_options) do
case Map.get(schema_options, :file_identifier) do
# nothing in schema
nil -> :ok
# schema matches data
^identifier_data -> :ok
# defined in schema but data says something else
identifier_schema -> throw({:error, {:identifier_mismatch, %{data: identifier_data, schema: identifier_schema}}})
end
end
def read(data, schema_str) when is_binary(schema_str) do
case parse_schema(schema_str) do
{:ok, schema} -> read(data, schema)
error -> error
end
end
def read(data, schema) do
try do
{:ok, read!(data, schema)}
catch
error -> error
rescue
error -> {:error, error}
end
end
def get(data, path, schema) do
try do
{:ok, get!(data, path, schema)}
catch
error -> error
rescue
error -> {:error, error}
end
end
def get!(data, path, schema) when is_binary(schema) do
get!(data, path, parse_schema!(schema))
end
def get!(data, path, {_tables, %{root_type: root_type}} = schema) do
Eflatbuffers.RandomAccess.get(path, {:table, %{ name: root_type }}, 0, data, schema)
end
end