Skip to content
This repository has been archived by the owner on May 25, 2021. It is now read-only.

Commit

Permalink
Add improved implementation of percent encoding/decoding functions.
Browse files Browse the repository at this point in the history
  • Loading branch information
Tim Fletcher committed Oct 6, 2009
1 parent be1aa96 commit ca45418
Showing 1 changed file with 38 additions and 28 deletions.
66 changes: 38 additions & 28 deletions src/oauth_uri.erl
Original file line number Diff line number Diff line change
Expand Up @@ -6,14 +6,6 @@

-import(lists, [concat/1]).

-define(is_uppercase_alpha(C), C >= $A, C =< $Z).
-define(is_lowercase_alpha(C), C >= $a, C =< $z).
-define(is_alpha(C), ?is_uppercase_alpha(C); ?is_lowercase_alpha(C)).
-define(is_digit(C), C >= $0, C =< $9).
-define(is_alphanumeric(C), ?is_alpha(C); ?is_digit(C)).
-define(is_unreserved(C), ?is_alphanumeric(C); C =:= $-; C =:= $_; C =:= $.; C =:= $~).
-define(is_hex(C), ?is_digit(C); C >= $A, C =< $F).


normalize(URI) ->
case http_uri:parse(URI) of
Expand Down Expand Up @@ -66,23 +58,41 @@ intersperse(_, [X]) -> [X];
intersperse(Sep, [X|Xs]) ->
[X, Sep|intersperse(Sep, Xs)].

decode(Chars) ->
decode(Chars, []).

decode([], Decoded) ->
lists:reverse(Decoded);
decode([$%,A,B|Etc], Decoded) when ?is_hex(A), ?is_hex(B) ->
decode(Etc, [erlang:list_to_integer([A,B], 16)|Decoded]);
decode([C|Etc], Decoded) when ?is_unreserved(C) ->
decode(Etc, [C|Decoded]).

encode(Chars) ->
encode(Chars, []).

encode([], Encoded) ->
lists:flatten(lists:reverse(Encoded));
encode([C|Etc], Encoded) when ?is_unreserved(C) ->
encode(Etc, [C|Encoded]);
encode([C|Etc], Encoded) ->
Value = io_lib:format("%~2.1.0s", [erlang:integer_to_list(C, 16)]),
encode(Etc, [Value|Encoded]).
-define(is_alphanum(C), C >= $A, C =< $Z; C >= $a, C =< $z; C >= $0, C =< $9).

encode(Term) when is_integer(Term) ->
integer_to_list(Term);
encode(Term) when is_atom(Term) ->
encode(atom_to_list(Term));
encode(Term) when is_list(Term) ->
encode(lists:reverse(Term, []), []).

encode([X | T], Acc) when ?is_alphanum(X); X =:= $-; X =:= $_; X =:= $.; X =:= $~ ->
encode(T, [X | Acc]);
encode([X | T], Acc) ->
NewAcc = [$%, dec2hex(X bsr 4), dec2hex(X band 16#0f) | Acc],
encode(T, NewAcc);
encode([], Acc) ->
Acc.

decode(Str) when is_list(Str) ->
decode(Str, []).

decode([$%, A, B | T], Acc) ->
decode(T, [(hex2dec(A) bsl 4) + hex2dec(B) | Acc]);
decode([X | T], Acc) ->
decode(T, [X | Acc]);
decode([], Acc) ->
lists:reverse(Acc, []).

-compile({inline, [{dec2hex, 1}, {hex2dec, 1}]}).

dec2hex(N) when N >= 10 andalso N =< 15 ->
N + $A - 10;
dec2hex(N) when N >= 0 andalso N =< 9 ->
N + $0.

hex2dec(C) when C >= $A andalso C =< $F ->
C - $A + 10;
hex2dec(C) when C >= $0 andalso C =< $9 ->
C - $0.

0 comments on commit ca45418

Please sign in to comment.