Skip to content

Commit 08549bf

Browse files
committed
WIP (Merge binaries, exts, collections handling into main function)
1 parent 5e3a213 commit 08549bf

File tree

1 file changed

+37
-57
lines changed

1 file changed

+37
-57
lines changed

Diff for: lib/msgpax/unpacker.ex

+37-57
Original file line numberDiff line numberDiff line change
@@ -25,7 +25,7 @@ defmodule Msgpax.Unpacker do
2525
@moduledoc false
2626

2727
def unpack(<<buffer::bits>>, options) do
28-
unpack(buffer, [], options)
28+
unpack(buffer, [], options, [:root], 0, 1)
2929
end
3030

3131
formats = %{
@@ -61,14 +61,14 @@ defmodule Msgpax.Unpacker do
6161
quote(do: [0xD3, val::64-signed-integer]) => {:value, quote(do: val)},
6262

6363
# Array
64-
quote(do: [0b1001::4, len::4]) => {:call, quote(do: unpack_list(len))},
65-
quote(do: [0xDC, len::16]) => {:call, quote(do: unpack_list(len))},
66-
quote(do: [0xDD, len::32]) => {:call, quote(do: unpack_list(len))},
64+
quote(do: [0b1001::4, len::4]) => {:collection, :list},
65+
quote(do: [0xDC, len::16]) => {:collection, :list},
66+
quote(do: [0xDD, len::32]) => {:collection, :list},
6767

6868
# Map
69-
quote(do: [0b1000::4, len::4]) => {:call, quote(do: unpack_map(len))},
70-
quote(do: [0xDE, len::16]) => {:call, quote(do: unpack_map(len))},
71-
quote(do: [0xDF, len::32]) => {:call, quote(do: unpack_map(len))},
69+
quote(do: [0b1000::4, len::4]) => {:collection, :map},
70+
quote(do: [0xDE, len::16]) => {:collection, :map},
71+
quote(do: [0xDF, len::32]) => {:collection, :map},
7272

7373
# Extension
7474
quote(do: [0xD4, type, val::1-bytes]) => {:call, quote(do: unpack_ext(type, val))},
@@ -84,77 +84,65 @@ defmodule Msgpax.Unpacker do
8484
import Macro, only: [pipe: 3]
8585

8686
for {format, {:value, value}} <- formats do
87-
defp unpack(<<unquote_splicing(format), rest::bits>>, [], options) do
88-
unpack(rest, [unquote(value)], options)
87+
defp unpack(<<unquote_splicing(format), rest::bits>>, result, options, outer, index, count) when index < count do
88+
unpack(rest, [unquote(value) | result], options, outer, index + 1, count)
8989
end
9090
end
9191

9292
for {format, {:call, call}} <- formats do
93-
rest = Macro.var(:rest, nil)
9493
options = Macro.var(:options, nil)
95-
defp unpack(<<unquote_splicing(format), rest::bits>>, [], options) do
96-
unquote(pipe(rest, pipe([], pipe(options, pipe([], call, 0), 0), 0), 0))
94+
defp unpack(<<unquote_splicing(format), rest::bits>>, result, options, outer, index, count) when index < count do
95+
unpack(rest, [unquote(pipe(options, call, 0)) | result], options, outer, index + 1, count)
9796
end
9897
end
9998

100-
defp unpack(<<byte, _::bits>>, [], _options) do
101-
throw {:bad_format, byte}
102-
end
103-
104-
defp unpack(<<_::bits>>, [], _options) do
105-
throw :incomplete
106-
end
107-
108-
defp unpack(buffer, [value], _options) do
109-
{value, buffer}
99+
for {format, {:collection, :list = kind}} <- formats do
100+
defp unpack(<<unquote_splicing(format), rest::bits>>, result, options, [kind | outer], index, count) when index < count do
101+
unpack(rest, result, options, [unquote(kind), {kind, index, count} | outer], 0, unquote(quote(do: len)))
102+
end
110103
end
111104

112-
defp unpack_binary(<<buffer::bits>>, result, %{binary: true} = options, outer, value) do
113-
unpack_continue(buffer, [Msgpax.Bin.new(value) | result], options, outer)
105+
for {format, {:collection, :map = kind}} <- formats do
106+
defp unpack(<<unquote_splicing(format), rest::bits>>, result, options, [kind | outer], index, count) when index < count do
107+
unpack(rest, result, options, [unquote(kind), {kind, index, count} | outer], 0, unquote(quote(do: len)) * 2)
108+
end
114109
end
115110

116-
defp unpack_binary(<<buffer::bits>>, result, options, outer, value) do
117-
unpack_continue(buffer, [value | result], options, outer)
111+
defp unpack(<<buffer::bits>>, result, options, [kind, {next, index, size} | outer], count, count) do
112+
unpack(buffer, build_collection(result, count, kind), options, [next | outer], index + 1, size)
118113
end
119114

120-
defp unpack_list(<<buffer::bits>>, result, options, outer, length) do
121-
unpack_collection(buffer, result, options, outer, 0, length, :list)
115+
defp unpack(<<byte, _::bits>>, [], _options, _outer, _index, _count) do
116+
throw {:bad_format, byte}
122117
end
123118

124-
for {format, {:value, value}} <- formats do
125-
defp unpack_collection(<<unquote_splicing(format), rest::bits>>, result, options, outer, index, length, kind) when index < length do
126-
unpack_collection(rest, [unquote(value) | result], options, outer, index + 1, length, kind)
127-
end
119+
defp unpack(<<_::bits>>, [], _options, _outer, _index, _count) do
120+
throw :incomplete
128121
end
129122

130-
for {format, {:call, call}} <- formats do
131-
rest = Macro.var(:rest, nil)
132-
result = Macro.var(:result, nil)
133-
options = Macro.var(:options, nil)
134-
outer = Macro.var(:outer, nil)
135-
defp unpack_collection(<<unquote_splicing(format), rest::bits>>, result, options, outer, index, length, kind) when index < length do
136-
outer = [{kind, index, length} | outer]
137-
unquote(pipe(rest, pipe(result, pipe(options, pipe(outer, call, 0), 0), 0), 0))
138-
end
123+
defp unpack(buffer, [value], _options, [:root], count, count) do
124+
{value, buffer}
139125
end
140126

141-
defp unpack_collection(<<buffer::bits>>, result, options, outer, count, count, kind) do
142-
unpack_continue(buffer, build_collection(result, count, kind), options, outer)
127+
defp unpack_binary(%{binary: true}, value) do
128+
Msgpax.Bin.new(value)
143129
end
144130

145-
defp unpack_map(<<buffer::bits>>, result, options, outer, length) do
146-
unpack_collection(buffer, result, options, outer, 0, length * 2, :map)
131+
defp unpack_binary(_options, value) do
132+
value
147133
end
148134

149-
defp unpack_ext(<<buffer::bits>>, result, options, outer, type, data) do
135+
defp unpack_ext(options, type, data) do
150136
if type in 0..127 do
151-
unpack_continue(buffer, [unpack_ext(type, data, options) | result], options, outer)
137+
unpack_ext_module(type, data, options)
152138
else
153139
throw {:not_supported_ext, type}
154140
end
155141
end
156142

157-
defp unpack_ext(type, data, %{ext: module}) when is_atom(module) do
143+
@compile {:inline, [unpack_ext_module: 3]}
144+
145+
defp unpack_ext_module(type, data, %{ext: module}) when is_atom(module) do
158146
case module.unpack(Msgpax.Ext.new(type, data)) do
159147
{:ok, result} ->
160148
result
@@ -163,18 +151,10 @@ defmodule Msgpax.Unpacker do
163151
end
164152
end
165153

166-
defp unpack_ext(type, data, _options) do
154+
defp unpack_ext_module(type, data, _options) do
167155
Msgpax.Ext.new(type, data)
168156
end
169157

170-
defp unpack_continue(<<buffer::bits>>, result, options, [{kind, index, length} | outer]) do
171-
unpack_collection(buffer, result, options, outer, index + 1, length, kind)
172-
end
173-
174-
defp unpack_continue(<<buffer::bits>>, result, options, []) do
175-
unpack(buffer, result, options)
176-
end
177-
178158
@compile {:inline, [build_collection: 3]}
179159

180160
defp build_collection(result, count, :list) do

0 commit comments

Comments
 (0)