diff options
author | Mikael Pettersson <[email protected]> | 2017-09-12 13:36:45 +0200 |
---|---|---|
committer | Mikael Pettersson <[email protected]> | 2017-09-12 13:36:45 +0200 |
commit | 8b2705934fc8df02fd54dae20c1127faa1e3308d (patch) | |
tree | 589eea9e23b1608eee710e1d122a3b5ab316d567 /lib/stdlib | |
parent | ada0b0b9c760553430af8e812852dab7f8a501e5 (diff) | |
download | otp-8b2705934fc8df02fd54dae20c1127faa1e3308d.tar.gz otp-8b2705934fc8df02fd54dae20c1127faa1e3308d.tar.bz2 otp-8b2705934fc8df02fd54dae20c1127faa1e3308d.zip |
base64:decode(List) optimized reimplementation
Diffstat (limited to 'lib/stdlib')
-rw-r--r-- | lib/stdlib/src/base64.erl | 38 |
1 files changed, 37 insertions, 1 deletions
diff --git a/lib/stdlib/src/base64.erl b/lib/stdlib/src/base64.erl index 5885745fb1..0eea2c0f1a 100644 --- a/lib/stdlib/src/base64.erl +++ b/lib/stdlib/src/base64.erl @@ -115,7 +115,7 @@ encode_binary(Bin) -> decode(Bin) when is_binary(Bin) -> decode_binary(<<>>, Bin); decode(List) when is_list(List) -> - list_to_binary(decode_l(List)). + decode_list(<<>>, List). -spec mime_decode(Base64) -> Data when Base64 :: ascii_string() | ascii_binary(), @@ -262,6 +262,42 @@ mime_decode_binary_after_eq(Result0, <<>>, Eq) -> Result end. +decode_list(A, [C1 | Cs]) -> + case element(C1, ?DECODE_MAP) of + ws -> decode_list(A, Cs); + B1 -> decode_list(A, B1, Cs) + end; +decode_list(A, []) -> + A. + +decode_list(A, B1, [C2 | Cs]) -> + case element(C2, ?DECODE_MAP) of + ws -> decode_list(A, B1, Cs); + B2 -> decode_list(A, B1, B2, Cs) + end. + +decode_list(A, B1, B2, [C3 | Cs]) -> + case element(C3, ?DECODE_MAP) of + ws -> decode_list(A, B1, B2, Cs); + B3 -> decode_list(A, B1, B2, B3, Cs) + end. + +decode_list(A, B1, B2, B3, [C4 | Cs]) -> + case element(C4, ?DECODE_MAP) of + ws -> decode_list(A, B1, B2, B3, Cs); + eq when B3 =:= eq -> only_ws(<<A/binary,B1:6,(B2 bsr 4):2>>, Cs); + eq -> only_ws(<<A/binary,B1:6,B2:6,(B3 bsr 2):4>>, Cs); + B4 -> decode_list(<<A/binary,B1:6,B2:6,B3:6,B4:6>>, Cs) + end. + +only_ws(A, []) -> + A; +only_ws(A, [C | Cs]) -> + case element(C, ?DECODE_MAP) of + ws -> only_ws(A, Cs); + _ -> erlang:error(function_clause) + end. + decode([], A) -> A; decode([$=,$=,C2,C1|Cs], A) -> Bits2x6 = (b64d(C1) bsl 18) bor (b64d(C2) bsl 12), |