Skip to content

Commit 9e2c5a2

Browse files
author
José Valim
committed
Speed up decode_www_form
Signed-off-by: José Valim <[email protected]>
1 parent 0949842 commit 9e2c5a2

File tree

1 file changed

+11
-9
lines changed

1 file changed

+11
-9
lines changed

lib/elixir/lib/uri.ex

Lines changed: 11 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -234,7 +234,7 @@ defmodule URI do
234234
235235
"""
236236
def decode(uri) do
237-
unpercent(uri)
237+
unpercent(uri, "", false)
238238
catch
239239
:malformed_uri ->
240240
raise ArgumentError, "malformed URI #{inspect uri}"
@@ -250,23 +250,25 @@ defmodule URI do
250250
251251
"""
252252
def decode_www_form(str) do
253-
String.split(str, "+") |> Enum.map_join(" ", &unpercent/1)
253+
unpercent(str, "", true)
254254
catch
255255
:malformed_uri ->
256256
raise ArgumentError, "malformed URI #{inspect str}"
257257
end
258258

259-
defp unpercent(<<?%, hex_1, hex_2, tail :: binary>>) do
260-
<<bsl(hex_to_dec(hex_1), 4) + hex_to_dec(hex_2)>> <> unpercent(tail)
259+
defp unpercent(<<?+, tail::binary>>, acc, spaces = true) do
260+
unpercent(tail, <<acc::binary, ?\s>>, spaces)
261261
end
262-
defp unpercent(<<?%, _>>), do: throw(:malformed_uri)
263-
defp unpercent(<<?%>>), do: throw(:malformed_uri)
264262

265-
defp unpercent(<<head, tail :: binary>>) do
266-
<<head>> <> unpercent(tail)
263+
defp unpercent(<<?%, hex_1, hex_2, tail::binary>>, acc, spaces) do
264+
unpercent(tail, <<acc::binary, bsl(hex_to_dec(hex_1), 4) + hex_to_dec(hex_2)>>, spaces)
267265
end
266+
defp unpercent(<<?%, _::binary>>, _acc, _spaces), do: throw(:malformed_uri)
268267

269-
defp unpercent(<<>>), do: <<>>
268+
defp unpercent(<<head, tail::binary>>, acc, spaces) do
269+
unpercent(tail, <<acc::binary, head>>, spaces)
270+
end
271+
defp unpercent(<<>>, acc, _spaces), do: acc
270272

271273
defp hex_to_dec(n) when n in ?A..?F, do: n - ?A + 10
272274
defp hex_to_dec(n) when n in ?a..?f, do: n - ?a + 10

0 commit comments

Comments
 (0)