add decoders and high-level decoder

This commit is contained in:
glyph 2022-09-22 15:29:48 +01:00
parent ae2011dbc6
commit 201a5ed512
2 changed files with 129 additions and 1 deletions

View File

@ -16,6 +16,8 @@ defmodule SsbBfe do
:world
end
# ENCODE
def encode(value) when is_list(value) do
Enum.map(value, fn x -> encode(x) end)
end
@ -31,7 +33,8 @@ defmodule SsbBfe do
end
def encode(value) when is_tuple(value) do
Enum.map(Tuple.to_list(value), fn x -> encode(x) end)
Enum.map(Tuple.to_list(value), fn x -> encode(x) end) |>
List.to_tuple()
end
def encode(value) when is_bitstring(value) do
@ -61,4 +64,54 @@ defmodule SsbBfe do
def encode(value) when is_number(value), do: value
def encode(value) when is_nil(value), do: SsbBfe.Encoder.encode_nil()
# DECODE
def decode(value) when is_binary(value) do
first_byte = :binary.first(value)
cond do
0 == first_byte ->
SsbBfe.Decoder.decode_feed(value)
1 == first_byte ->
SsbBfe.Decoder.decode_msg(value)
2 == first_byte ->
SsbBfe.Decoder.decode_blob(value)
4 == first_byte ->
SsbBfe.Decoder.decode_sig(value)
5 == first_byte ->
SsbBfe.Decoder.decode_box(value)
6 == first_byte ->
SsbBfe.Decoder.decode_generic(value)
nil ->
true
end
end
def decode(value) when is_number(value), do: value
def decode(value) when is_list(value) do
Enum.map(value, fn x -> decode(x) end)
end
def decode(value) when is_map(value) do
Enum.reduce(
value,
%{},
fn {k, v}, acc ->
Map.put(acc, k, SsbBfe.decode(v))
end
)
end
def decode(value) when is_tuple(value) do
Enum.map(Tuple.to_list(value), fn x -> decode(x) end) |>
List.to_tuple()
end
end

75
lib/ssb_bfe/decoder.ex Normal file
View File

@ -0,0 +1,75 @@
defmodule SsbBfe.Decoder do
defp extract_base64_data(bin, tf_tag) do
[_, base64_data] = :binary.split(bin, tf_tag)
Base.encode64(base64_data)
end
def decode_blob(blob) do
encoded_base64_data = extract_base64_data(blob, <<2, 0>>)
"&" <> encoded_base64_data <> ".sha256"
end
def decode_box(box) do
tf_tag = binary_part(box, 0, 2)
decode_box(box, tf_tag)
end
# Matches box.
def decode_box(box, <<5, 0>>) do
encoded_base64_data = extract_base64_data(box, <<5, 0>>)
encoded_base64_data <> ".box"
end
# Matches box2.
def decode_box(box, <<5, 1>>) do
encoded_base64_data = extract_base64_data(box, <<5, 1>>)
encoded_base64_data <> ".box2"
end
def decode_feed(feed) do
tf_tag = binary_part(feed, 0, 2)
decode_feed(feed, tf_tag)
end
# Matches classic feed.
def decode_feed(feed, <<0, 0>>) do
encoded_base64_data = extract_base64_data(feed, <<0, 0>>)
"@" <> encoded_base64_data <> ".ed25519"
end
def decode_generic(<<6, 1, 1>>), do: true
def decode_generic(<<6, 1, 0>>), do: false
def decode_generic(<<6, 2>>), do: nil
def decode_generic(generic) do
tf_tag = binary_part(generic, 0, 2)
decode_generic(generic, tf_tag)
end
# Matches generic string.
def decode_generic(str, <<6, 0>>) do
[_, str_data] = :binary.split(str, <<6, 0>>)
str_data
end
# Matches generic bytes.
def decode_generic(bytes, <<6, 3>>), do: bytes
def decode_msg(msg) do
tf_tag = binary_part(msg, 0, 2)
decode_msg(msg, tf_tag)
end
# Matches classic message.
def decode_msg(msg, <<1, 0>>) do
encoded_base64_data = extract_base64_data(msg, <<1, 0>>)
"%" <> encoded_base64_data <> ".sha256"
end
def decode_sig(sig) do
encoded_base64_data = extract_base64_data(sig, <<4, 0>>)
encoded_base64_data <> ".sig.ed25519"
end
end