Implement UDP data parsing.
[erlang-x-plane-data.git] / src / x_plane_data.erl
diff --git a/src/x_plane_data.erl b/src/x_plane_data.erl
new file mode 100644 (file)
index 0000000..207673d
--- /dev/null
@@ -0,0 +1,49 @@
+-module(x_plane_data).
+
+-include("x_plane_datum_defaults.hrl").
+
+-export_type(
+    [ t/0
+    ]).
+
+-export(
+    [ of_bin/1
+    ]).
+
+-type parsing_error() ::
+      packet_unrecognized
+    | packet_length_invalid
+    | x_plane_datum:parsing_error()
+    .
+
+-type t() ::
+    [x_plane_datum:t()].
+
+-define(BYTE_SIZE_OF_EACH_BLOCK, 36).
+
+-spec of_bin(binary()) ->
+    hope_result:t(t(), parsing_error()).
+of_bin(<<Packet/binary>>) ->
+    of_bin(Packet, ?DEFAULT_MAX_INDEX).
+
+-spec of_bin(binary(), non_neg_integer()) ->
+    hope_result:t(t(), parsing_error()).
+of_bin(<<"DATA", _PacketIndexByte:1/bytes, ContiguousBlocks/binary>>, MaxIndex) ->
+    % Packet index byte seems to be changing from X-Plane version to verion.
+    % What is it's meaning?
+    if byte_size(ContiguousBlocks) rem ?BYTE_SIZE_OF_EACH_BLOCK =:= 0 ->
+            Blocks = blocks_split(ContiguousBlocks),
+            ParseBlock = fun (B) -> x_plane_datum:of_bin(B, MaxIndex) end,
+            hope_list:map_result(Blocks, ParseBlock)
+    ;  true ->
+            {error, packet_length_invalid}
+    end;
+of_bin(<<_/binary>>, _) ->
+    {error, packet_unrecognized}.
+
+-spec blocks_split(binary()) ->
+    [binary()].
+blocks_split(<<>>) ->
+    [];
+blocks_split(<<Block:?BYTE_SIZE_OF_EACH_BLOCK/bytes, Blocks/binary>>) ->
+    [Block | blocks_split(Blocks)].
This page took 0.03069 seconds and 4 git commands to generate.