Skip to content
Merged
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
154 changes: 81 additions & 73 deletions lib/elixir/lib/base.ex
Original file line number Diff line number Diff line change
Expand Up @@ -1268,14 +1268,10 @@ defmodule Base do
pad? = Keyword.get(opts, :padding, true)

case Keyword.get(opts, :case, :upper) do
:upper -> validate32upper!(string, pad?)
:lower -> validate32lower!(string, pad?)
:mixed -> validate32mixed!(string, pad?)
:upper -> validate32upper?(string, pad?)
:lower -> validate32lower?(string, pad?)
:mixed -> validate32mixed?(string, pad?)
end

true
rescue
ArgumentError -> false
end

@doc """
Expand Down Expand Up @@ -1406,14 +1402,10 @@ defmodule Base do
pad? = Keyword.get(opts, :padding, true)

case Keyword.get(opts, :case, :upper) do
:upper -> validate32hexupper!(string, pad?)
:lower -> validate32hexlower!(string, pad?)
:mixed -> validate32hexmixed!(string, pad?)
:upper -> validate32hexupper?(string, pad?)
:lower -> validate32hexlower?(string, pad?)
:mixed -> validate32hexmixed?(string, pad?)
end

true
rescue
ArgumentError -> false
end

upper = Enum.with_index(b32_alphabet)
Expand All @@ -1428,96 +1420,112 @@ defmodule Base do
hexmixed: to_mixed_dec.(hexupper)
] do
decode_name = :"decode32#{base}!"
validate_name = :"validate32#{base}!"
validate_name = :"validate32#{base}?"
validate_main_name = :"validate_main32#{validate_name}?"
valid_char_name = :"valid_char32#{base}?"
{min, decoded} = to_decode_list.(alphabet)

defp unquote(validate_name)(<<>>, _pad?) do
:ok
defp unquote(validate_main_name)(<<>>), do: true

defp unquote(validate_main_name)(
<<c1::8, c2::8, c3::8, c4::8, c5::8, c6::8, c7::8, c8::8, rest::binary>>
) do
unquote(valid_char_name)(c1) and
unquote(valid_char_name)(c2) and
unquote(valid_char_name)(c3) and
unquote(valid_char_name)(c4) and
unquote(valid_char_name)(c5) and
unquote(valid_char_name)(c6) and
unquote(valid_char_name)(c7) and
unquote(valid_char_name)(c8) and
unquote(validate_main_name)(rest)
end

defp unquote(validate_name)(<<>>, _pad?), do: true

defp unquote(validate_name)(string, pad?) do
segs = div(byte_size(string) + 7, 8) - 1
<<main::size(^segs)-binary-unit(64), rest::binary>> = string

for <<c1::8, c2::8, c3::8, c4::8, c5::8, c6::8, c7::8, c8::8 <- main>> do
unquote(decode_name)(c1)
unquote(decode_name)(c2)
unquote(decode_name)(c3)
unquote(decode_name)(c4)
unquote(decode_name)(c5)
unquote(decode_name)(c6)
unquote(decode_name)(c7)
unquote(decode_name)(c8)
end
main_valid? = unquote(validate_main_name)(main)

case rest do
_ when not main_valid? ->
false

<<c1::8, c2::8, ?=, ?=, ?=, ?=, ?=, ?=>> ->
unquote(decode_name)(c1)
unquote(decode_name)(c2)
unquote(valid_char_name)(c1) and
unquote(valid_char_name)(c2)

<<c1::8, c2::8, c3::8, c4::8, ?=, ?=, ?=, ?=>> ->
unquote(decode_name)(c1)
unquote(decode_name)(c2)
unquote(decode_name)(c3)
unquote(decode_name)(c4)
unquote(valid_char_name)(c1) and
unquote(valid_char_name)(c2) and
unquote(valid_char_name)(c3) and
unquote(valid_char_name)(c4)

<<c1::8, c2::8, c3::8, c4::8, c5::8, ?=, ?=, ?=>> ->
unquote(decode_name)(c1)
unquote(decode_name)(c2)
unquote(decode_name)(c3)
unquote(decode_name)(c4)
unquote(decode_name)(c5)
unquote(valid_char_name)(c1) and
unquote(valid_char_name)(c2) and
unquote(valid_char_name)(c3) and
unquote(valid_char_name)(c4) and
unquote(valid_char_name)(c5)

<<c1::8, c2::8, c3::8, c4::8, c5::8, c6::8, c7::8, ?=>> ->
unquote(decode_name)(c1)
unquote(decode_name)(c2)
unquote(decode_name)(c3)
unquote(decode_name)(c4)
unquote(decode_name)(c5)
unquote(decode_name)(c6)
unquote(decode_name)(c7)
unquote(valid_char_name)(c1) and
unquote(valid_char_name)(c2) and
unquote(valid_char_name)(c3) and
unquote(valid_char_name)(c4) and
unquote(valid_char_name)(c5) and
unquote(valid_char_name)(c6) and
unquote(valid_char_name)(c7)

<<c1::8, c2::8, c3::8, c4::8, c5::8, c6::8, c7::8, c8::8>> ->
unquote(decode_name)(c1)
unquote(decode_name)(c2)
unquote(decode_name)(c3)
unquote(decode_name)(c4)
unquote(decode_name)(c5)
unquote(decode_name)(c6)
unquote(decode_name)(c7)
unquote(decode_name)(c8)
unquote(valid_char_name)(c1) and
unquote(valid_char_name)(c2) and
unquote(valid_char_name)(c3) and
unquote(valid_char_name)(c4) and
unquote(valid_char_name)(c5) and
unquote(valid_char_name)(c6) and
unquote(valid_char_name)(c7) and
unquote(valid_char_name)(c8)

<<c1::8, c2::8>> when not pad? ->
unquote(decode_name)(c1)
unquote(decode_name)(c2)
unquote(valid_char_name)(c1) and
unquote(valid_char_name)(c2)

<<c1::8, c2::8, c3::8, c4::8>> when not pad? ->
unquote(decode_name)(c1)
unquote(decode_name)(c2)
unquote(decode_name)(c3)
unquote(decode_name)(c4)
unquote(valid_char_name)(c1) and
unquote(valid_char_name)(c2) and
unquote(valid_char_name)(c3) and
unquote(valid_char_name)(c4)

<<c1::8, c2::8, c3::8, c4::8, c5::8>> when not pad? ->
unquote(decode_name)(c1)
unquote(decode_name)(c2)
unquote(decode_name)(c3)
unquote(decode_name)(c4)
unquote(decode_name)(c5)
unquote(valid_char_name)(c1) and
unquote(valid_char_name)(c2) and
unquote(valid_char_name)(c3) and
unquote(valid_char_name)(c4) and
unquote(valid_char_name)(c5)

<<c1::8, c2::8, c3::8, c4::8, c5::8, c6::8, c7::8>> when not pad? ->
unquote(decode_name)(c1)
unquote(decode_name)(c2)
unquote(decode_name)(c3)
unquote(decode_name)(c4)
unquote(decode_name)(c5)
unquote(decode_name)(c6)
unquote(decode_name)(c7)
unquote(valid_char_name)(c1) and
unquote(valid_char_name)(c2) and
unquote(valid_char_name)(c3) and
unquote(valid_char_name)(c4) and
unquote(valid_char_name)(c5) and
unquote(valid_char_name)(c6) and
unquote(valid_char_name)(c7)

_ ->
raise ArgumentError, "incorrect padding"
false
end
end

@compile {:inline, [{valid_char_name, 1}]}
defp unquote(valid_char_name)(char)
when elem({unquote_splicing(decoded)}, char - unquote(min)) != nil,
do: true

defp unquote(valid_char_name)(_char), do: false

defp unquote(decode_name)(char) do
index = char - unquote(min)

Expand Down
Loading