this repo has no description
2
fork

Configure Feed

Select the types of activity you want to include in your feed.

Rename encoding module/functions

garrison 67c6a3ce d975e494

+58 -58
+49 -49
lib/encoding/keyset.ex
··· 1 - defmodule Hobbes.Enc do 1 + defmodule Hobbes.Encoding.Keyset do 2 2 @moduledoc """ 3 3 Encodings for Hobbes keys and values. 4 4 """ ··· 18 18 @int_pos_7 0x1C 19 19 @int_pos_8 0x1D 20 20 21 - @spec encode_key(list) :: binary 22 - def encode_key(list) when is_list(list) do 23 - enc_key(list, 0) 21 + @spec pack(list) :: binary 22 + def pack(list) when is_list(list) do 23 + encode(list, 0) 24 24 |> IO.iodata_to_binary() 25 25 end 26 26 27 - @spec decode_key(binary) :: list 28 - def decode_key(binary) when is_binary(binary) do 29 - case dec_key(binary, 0) do 27 + @spec unpack(binary) :: list 28 + def unpack(binary) when is_binary(binary) do 29 + case decode(binary, 0) do 30 30 {values, ""} -> 31 31 values 32 32 end 33 33 end 34 34 35 - defp enc_key(nil, 0), do: <<@nil_value>> 36 - defp enc_key(nil, depth) when depth > 0, do: <<@nil_value, @escape>> 35 + defp encode(nil, 0), do: <<@nil_value>> 36 + defp encode(nil, depth) when depth > 0, do: <<@nil_value, @escape>> 37 37 38 - defp enc_key(list, 0) when is_list(list) do 39 - Enum.map(list, &enc_key(&1, 1)) 38 + defp encode(list, 0) when is_list(list) do 39 + Enum.map(list, &encode(&1, 1)) 40 40 end 41 41 42 - defp enc_key(list, depth) when is_list(list) and depth > 0 do 43 - values = Enum.map(list, &enc_key(&1, depth + 1)) 42 + defp encode(list, depth) when is_list(list) and depth > 0 do 43 + values = Enum.map(list, &encode(&1, depth + 1)) 44 44 [@nested_list, values, @nil_value] 45 45 end 46 46 47 - defp enc_key(binary, _depth) when is_binary(binary) do 48 - [<<@binary>>, enc_binary(binary, 0)] 47 + defp encode(binary, _depth) when is_binary(binary) do 48 + [<<@binary>>, encode_binary(binary, 0)] 49 49 end 50 50 51 - defp enc_key(0, _depth) do 51 + defp encode(0, _depth) do 52 52 <<@int_0>> 53 53 end 54 54 55 - defp enc_key(int, _depth) when is_integer(int) and int > 0 do 55 + defp encode(int, _depth) when is_integer(int) and int > 0 do 56 56 binary = :binary.encode_unsigned(int) 57 57 case byte_size(binary) do 58 58 1 -> [<<@int_pos_1>>, binary] ··· 67 67 end 68 68 69 69 # Encodes a null-terminated binary, nulls are escaped as <<0x00, 0xFF>> 70 - defp enc_binary(binary, offset) do 70 + defp encode_binary(binary, offset) do 71 71 case binary do 72 72 <<head::binary-size(offset)>> -> 73 73 # Terminate encoded binary (null-terminated) ··· 75 75 76 76 <<head::binary-size(offset), 0x00, tail::binary>> -> 77 77 # Escape null value in binary and keep going 78 - [head, <<@nil_value, @escape>> | enc_binary(tail, 0)] 78 + [head, <<@nil_value, @escape>> | encode_binary(tail, 0)] 79 79 80 80 <<_head::binary-size(offset), _other, _tail::binary>> -> 81 81 # Non-null character, keep scanning 82 - enc_binary(binary, offset + 1) 82 + encode_binary(binary, offset + 1) 83 83 end 84 84 end 85 85 86 - defp dec_key("", 0) do 86 + defp decode("", 0) do 87 87 {[], ""} 88 88 end 89 89 90 - defp dec_key(<<@nil_value, rest::binary>>, 0 = depth) do 91 - {values, tail} = dec_key(rest, depth) 90 + defp decode(<<@nil_value, rest::binary>>, 0 = depth) do 91 + {values, tail} = decode(rest, depth) 92 92 {[nil | values], tail} 93 93 end 94 94 95 95 # Escaped nil within a nested list 96 - defp dec_key(<<@nil_value, @escape, rest::binary>>, depth) when depth > 0 do 97 - {values, tail} = dec_key(rest, depth) 96 + defp decode(<<@nil_value, @escape, rest::binary>>, depth) when depth > 0 do 97 + {values, tail} = decode(rest, depth) 98 98 {[nil | values], tail} 99 99 end 100 100 101 101 # Closing a nested list 102 - defp dec_key(<<@nil_value, rest::binary>>, depth) when depth > 0 do 102 + defp decode(<<@nil_value, rest::binary>>, depth) when depth > 0 do 103 103 {[], rest} 104 104 end 105 105 106 - defp dec_key(<<@binary, rest::binary>>, depth) do 107 - {decoded_binary, rest} = dec_binary(rest) 108 - {values, tail} = dec_key(rest, depth) 106 + defp decode(<<@binary, rest::binary>>, depth) do 107 + {decoded_binary, rest} = decode_binary(rest) 108 + {values, tail} = decode(rest, depth) 109 109 {[decoded_binary | values], tail} 110 110 end 111 111 112 - defp dec_key(<<@nested_list, rest::binary>>, depth) do 113 - {nested_values, rest} = dec_key(rest, depth + 1) 114 - {values, tail} = dec_key(rest, depth) 112 + defp decode(<<@nested_list, rest::binary>>, depth) do 113 + {nested_values, rest} = decode(rest, depth + 1) 114 + {values, tail} = decode(rest, depth) 115 115 {[nested_values | values], tail} 116 116 end 117 117 118 - defp dec_key(<<@int_0, rest::binary>>, depth) do 119 - {values, tail} = dec_key(rest, depth) 118 + defp decode(<<@int_0, rest::binary>>, depth) do 119 + {values, tail} = decode(rest, depth) 120 120 {[0 | values], tail} 121 121 end 122 122 123 - defp dec_key(<<@int_pos_1, rest::binary>>, depth), do: dec_pos_integer(1, rest, depth) 124 - defp dec_key(<<@int_pos_2, rest::binary>>, depth), do: dec_pos_integer(2, rest, depth) 125 - defp dec_key(<<@int_pos_3, rest::binary>>, depth), do: dec_pos_integer(3, rest, depth) 126 - defp dec_key(<<@int_pos_4, rest::binary>>, depth), do: dec_pos_integer(4, rest, depth) 127 - defp dec_key(<<@int_pos_5, rest::binary>>, depth), do: dec_pos_integer(5, rest, depth) 128 - defp dec_key(<<@int_pos_6, rest::binary>>, depth), do: dec_pos_integer(6, rest, depth) 129 - defp dec_key(<<@int_pos_7, rest::binary>>, depth), do: dec_pos_integer(7, rest, depth) 130 - defp dec_key(<<@int_pos_8, rest::binary>>, depth), do: dec_pos_integer(8, rest, depth) 123 + defp decode(<<@int_pos_1, rest::binary>>, depth), do: dec_pos_int(1, rest, depth) 124 + defp decode(<<@int_pos_2, rest::binary>>, depth), do: dec_pos_int(2, rest, depth) 125 + defp decode(<<@int_pos_3, rest::binary>>, depth), do: dec_pos_int(3, rest, depth) 126 + defp decode(<<@int_pos_4, rest::binary>>, depth), do: dec_pos_int(4, rest, depth) 127 + defp decode(<<@int_pos_5, rest::binary>>, depth), do: dec_pos_int(5, rest, depth) 128 + defp decode(<<@int_pos_6, rest::binary>>, depth), do: dec_pos_int(6, rest, depth) 129 + defp decode(<<@int_pos_7, rest::binary>>, depth), do: dec_pos_int(7, rest, depth) 130 + defp decode(<<@int_pos_8, rest::binary>>, depth), do: dec_pos_int(8, rest, depth) 131 131 132 - defp dec_binary(binary) do 133 - {parts, tail} = dec_binary(binary, 0) 132 + defp decode_binary(binary) do 133 + {parts, tail} = decode_binary(binary, 0) 134 134 {IO.iodata_to_binary(parts), tail} 135 135 end 136 136 137 - defp dec_binary(binary, offset) do 137 + defp decode_binary(binary, offset) do 138 138 case binary do 139 139 <<head::binary-size(offset), @nil_value, @escape, bin_tail::binary>> -> 140 140 # Un-escape null byte and keep going 141 - {parts, tail} = dec_binary(bin_tail, 0) 141 + {parts, tail} = decode_binary(bin_tail, 0) 142 142 {[head, "\x00" | parts], tail} 143 143 144 144 <<head::binary-size(offset), @nil_value, tail::binary>> -> ··· 147 147 148 148 <<_head::binary-size(offset), _other, _tail::binary>> -> 149 149 # Found any other byte, keep scanning 150 - dec_binary(binary, offset + 1) 150 + decode_binary(binary, offset + 1) 151 151 152 152 <<_head::binary-size(offset)>> -> raise "Encoded binary was not terminated: #{inspect(binary)}" 153 153 end 154 154 end 155 155 156 - defp dec_pos_integer(bytes, rest, depth) do 156 + defp dec_pos_int(bytes, rest, depth) do 157 157 <<int::unsigned-big-integer-size(bytes)-unit(8), rest::binary>> = rest 158 158 159 - {values, tail} = dec_key(rest, depth) 159 + {values, tail} = decode(rest, depth) 160 160 {[int | values], tail} 161 161 end 162 162 end
+9 -9
test/encoding_test.exs
··· 1 1 defmodule Hobbes.EncTest do 2 2 use ExUnit.Case, async: true 3 3 4 - alias Hobbes.Enc 4 + alias Hobbes.Encoding.Keyset 5 5 6 - @moduletag :enc 6 + @moduletag :encoding 7 7 8 8 # TODO: fuzz 9 9 describe "tuples" do ··· 18 18 ] 19 19 20 20 for k <- keys do 21 - result = Enc.encode_key(k) |> Enc.decode_key() 21 + result = Keyset.pack(k) |> Keyset.unpack() 22 22 assert result == k 23 23 end 24 24 end ··· 32 32 ] 33 33 34 34 for k <- keys do 35 - result = Enc.encode_key(k) |> Enc.decode_key() 35 + result = Keyset.pack(k) |> Keyset.unpack() 36 36 assert result == k 37 37 end 38 38 end ··· 45 45 ] 46 46 47 47 for k <- keys do 48 - result = Enc.encode_key(k) |> Enc.decode_key() 48 + result = Keyset.pack(k) |> Keyset.unpack() 49 49 assert result == k 50 50 end 51 51 end 52 52 end 53 53 54 - describe "encode_key/1" do 54 + describe "pack/1" do 55 55 test "encodes integers" do 56 - assert "\x14" = Enc.encode_key([0]) 56 + assert "\x14" = Keyset.pack([0]) 57 57 58 - assert "\x17" <> rest = Enc.encode_key([1_000_000]) 58 + assert "\x17" <> rest = Keyset.pack([1_000_000]) 59 59 assert :binary.decode_unsigned(rest) == 1_000_000 60 60 61 - assert "\x1D" <> rest = Enc.encode_key([(2 ** 64) - 1]) 61 + assert "\x1D" <> rest = Keyset.pack([(2 ** 64) - 1]) 62 62 assert rest == String.duplicate("\xFF", 8) 63 63 end 64 64 end