Implement deserialization for varints and varlongs
All checks were successful
Build & Test / nix-build (push) Successful in 1m7s
All checks were successful
Build & Test / nix-build (push) Successful in 1m7s
This commit is contained in:
parent
502ca17bd3
commit
92325c05b1
40
lib/data.ex
40
lib/data.ex
@ -77,7 +77,7 @@ defmodule Amethyst.Minecraft.Read do
|
|||||||
{[], binary}
|
{[], binary}
|
||||||
end
|
end
|
||||||
|
|
||||||
def bool({acc, <<value, rest::bitstring>>}) do
|
def bool({acc, <<value, rest::binary>>}) do
|
||||||
{[value != 0 | acc], rest}
|
{[value != 0 | acc], rest}
|
||||||
end
|
end
|
||||||
|
|
||||||
@ -112,4 +112,42 @@ defmodule Amethyst.Minecraft.Read do
|
|||||||
def double({acc, <<value::64-float-big, rest::binary>>}) do
|
def double({acc, <<value::64-float-big, rest::binary>>}) do
|
||||||
{[value | acc], rest}
|
{[value | acc], rest}
|
||||||
end
|
end
|
||||||
|
|
||||||
|
def varint(tuple, read \\ 0, nacc \\ 0)
|
||||||
|
def varint({acc, <<1::1, value::7, rest::binary>>}, read, nacc) when read < 5 do
|
||||||
|
varint({acc, rest}, read + 1, nacc + (value <<< (7 * read)))
|
||||||
|
end
|
||||||
|
def varint({acc, <<0::1, value::7, rest::binary>>}, read, nacc) do
|
||||||
|
total = nacc + (value <<< (7 * read))
|
||||||
|
<<value::32-signed>> = <<total::32-unsigned>>
|
||||||
|
{[value | acc], rest}
|
||||||
|
end
|
||||||
|
def varint(_, read, _) when read >= 5 do
|
||||||
|
raise RuntimeError, "Got a varint which is too big!"
|
||||||
|
end
|
||||||
|
def varint({_, ""}, _, _) do
|
||||||
|
raise RuntimeError, "Got an incomplete varint!"
|
||||||
|
end
|
||||||
|
|
||||||
|
def varlong(tuple, read \\ 0, nacc \\ 0)
|
||||||
|
def varlong({acc, <<1::1, value::7, rest::binary>>}, read, nacc) when read < 10 do
|
||||||
|
varlong({acc, rest}, read + 1, nacc + (value <<< (7 * read)))
|
||||||
|
end
|
||||||
|
def varlong({acc, <<0::1, value::7, rest::binary>>}, read, nacc) do
|
||||||
|
total = nacc + (value <<< (7 * read))
|
||||||
|
<<value::64-signed>> = <<total::64-unsigned>>
|
||||||
|
{[value | acc], rest}
|
||||||
|
end
|
||||||
|
def varlong(_, read, _) when read >= 10 do
|
||||||
|
raise RuntimeError, "Got a varint which is too big!"
|
||||||
|
end
|
||||||
|
def varlong({_, ""}, _, _) do
|
||||||
|
raise RuntimeError, "Got an incomplete varint!"
|
||||||
|
end
|
||||||
|
|
||||||
|
def string({acc, data}) do
|
||||||
|
{[length], rest} = start(data) |> varint()
|
||||||
|
<<value::binary-size(length), rest::binary>> = rest
|
||||||
|
{[value | acc], rest}
|
||||||
|
end
|
||||||
end
|
end
|
||||||
|
@ -1,7 +1,11 @@
|
|||||||
defmodule WriteTest do
|
defmodule WriteTest do
|
||||||
use ExUnit.Case
|
use ExUnit.Case
|
||||||
|
|
||||||
|
@moduledoc """
|
||||||
|
This module contains tests for the Amethyst.Minecraft.Write module.
|
||||||
|
"""
|
||||||
|
|
||||||
doctest Amethyst.Minecraft.Write
|
doctest Amethyst.Minecraft.Write
|
||||||
doctest Amethyst.Minecraft.Read
|
|
||||||
|
|
||||||
test "writing a varint" do
|
test "writing a varint" do
|
||||||
assert Amethyst.Minecraft.Write.varint(0) == <<0x00>>
|
assert Amethyst.Minecraft.Write.varint(0) == <<0x00>>
|
||||||
@ -28,3 +32,38 @@ defmodule WriteTest do
|
|||||||
assert Amethyst.Minecraft.Write.string("") == <<0x00>>
|
assert Amethyst.Minecraft.Write.string("") == <<0x00>>
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|
||||||
|
defmodule ReadTest do
|
||||||
|
use ExUnit.Case
|
||||||
|
|
||||||
|
@moduledoc """
|
||||||
|
This module contains tests for the Amethyst.Minecraft.Read module.
|
||||||
|
"""
|
||||||
|
|
||||||
|
doctest Amethyst.Minecraft.Read
|
||||||
|
|
||||||
|
test "reading a varint" do
|
||||||
|
assert Amethyst.Minecraft.Read.start(<<0x00>>) |> Amethyst.Minecraft.Read.varint() == {[0], ""}
|
||||||
|
assert Amethyst.Minecraft.Read.start(<<0x7F>>) |> Amethyst.Minecraft.Read.varint() == {[127], ""}
|
||||||
|
assert Amethyst.Minecraft.Read.start(<<0x80, 0x01>>) |> Amethyst.Minecraft.Read.varint() == {[128], ""}
|
||||||
|
assert Amethyst.Minecraft.Read.start(<<0xFF, 0x01>>) |> Amethyst.Minecraft.Read.varint() == {[255], ""}
|
||||||
|
assert Amethyst.Minecraft.Read.start(<<0xFF, 0xFF, 0xFF, 0xFF, 0x07>>) |> Amethyst.Minecraft.Read.varint() == {[2_147_483_647], ""}
|
||||||
|
assert Amethyst.Minecraft.Read.start(<<0xFF, 0xFF, 0xFF, 0xFF, 0x0F>>) |> Amethyst.Minecraft.Read.varint() == {[-1], ""}
|
||||||
|
assert Amethyst.Minecraft.Read.start(<<0x80, 0x80, 0x80, 0x80, 0x08>>) |> Amethyst.Minecraft.Read.varint() == {[-2_147_483_648], ""}
|
||||||
|
end
|
||||||
|
|
||||||
|
test "reading a varlong" do
|
||||||
|
assert Amethyst.Minecraft.Read.start(<<0x00>>) |> Amethyst.Minecraft.Read.varlong() == {[0], ""}
|
||||||
|
assert Amethyst.Minecraft.Read.start(<<0x7F>>) |> Amethyst.Minecraft.Read.varlong() == {[127], ""}
|
||||||
|
assert Amethyst.Minecraft.Read.start(<<0x80, 0x01>>) |> Amethyst.Minecraft.Read.varlong() == {[128], ""}
|
||||||
|
assert Amethyst.Minecraft.Read.start(<<0xFF, 0x01>>) |> Amethyst.Minecraft.Read.varlong() == {[255], ""}
|
||||||
|
assert Amethyst.Minecraft.Read.start(<<0xFF, 0xFF, 0xFF, 0xFF, 0x07>>) |> Amethyst.Minecraft.Read.varlong() == {[2_147_483_647], ""}
|
||||||
|
assert Amethyst.Minecraft.Read.start(<<0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0x7F>>) |> Amethyst.Minecraft.Read.varlong() == {[9_223_372_036_854_775_807], ""}
|
||||||
|
assert Amethyst.Minecraft.Read.start(<<0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0x01>>) |> Amethyst.Minecraft.Read.varlong() == {[-1], ""}
|
||||||
|
end
|
||||||
|
|
||||||
|
test "reading a string" do
|
||||||
|
assert Amethyst.Minecraft.Read.start(<<0x0D, "Hello, world!">>) |> Amethyst.Minecraft.Read.string() == {["Hello, world!"], ""}
|
||||||
|
assert Amethyst.Minecraft.Read.start(<<0x00>>) |> Amethyst.Minecraft.Read.string() == {[""], ""}
|
||||||
|
end
|
||||||
|
end
|
||||||
|
Loading…
Reference in New Issue
Block a user