%% %% Copyright (c) 2016, Dmitry Kolesnikov %% Copyright (c) 2016, Mario Cardona %% All Rights Reserved. %% %% Licensed under the Apache License, Version 2.0 (the "License"); %% you may not use this file except in compliance with the License. %% You may obtain a copy of the License at %% %% http://www.apache.org/licenses/LICENSE-2.0 %% %% Unless required by applicable law or agreed to in writing, software %% distributed under the License is distributed on an "AS IS" BASIS, %% WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. %% See the License for the specific language governing permissions and %% limitations under the License. %% -module(m_http_codec_url). -export([escape/1, unescape/1]). %% %% escape escape(X) when is_binary(X) -> escape(X, <<>>); escape(X) -> escape(typecast:s(X)). escape(<>, Acc) when H >= $a, H =< $z -> escape(Bin, <>); escape(<>, Acc) when H >= $A, H =< $Z -> escape(Bin, <>); escape(<>, Acc) when H >= $0, H =< $9 -> escape(Bin, <>); escape(<<$ , Bin/binary>>, Acc) -> escape(Bin, <>); %% unreserved "-" | "_" | "." | "!" | "~" | "*" | "'" | "(" | ")" escape(<<$-, Bin/binary>>, Acc) -> escape(Bin, <>); escape(<<$_, Bin/binary>>, Acc) -> escape(Bin, <>); escape(<<$., Bin/binary>>, Acc) -> escape(Bin, <>); escape(<<$!, Bin/binary>>, Acc) -> escape(Bin, <>); escape(<<$~, Bin/binary>>, Acc) -> escape(Bin, <>); escape(<<$*, Bin/binary>>, Acc) -> escape(Bin, <>); escape(<<$', Bin/binary>>, Acc) -> escape(Bin, <>); escape(<<$(, Bin/binary>>, Acc) -> escape(Bin, <>); escape(<<$), Bin/binary>>, Acc) -> escape(Bin, <>); escape(<>, Acc) when H =< 16#7f -> escape(Bin, <>); escape(<>, Acc) when H > 16#7f -> escape(Bin, <> ); escape(<<>>, Acc) -> Acc. escape_byte(H) -> <<(hex(H div 16)), (hex(H rem 16))>>. hex(H) when H < 10 -> $0 + H; hex(H) when H >= 10 -> $A + (H - 10). %% %% unescape unescape(Bin) -> decode(unescape(Bin, <<>>), <<>>). unescape(<<$%, H:8, L:8, Bin/binary>>, Acc) -> unescape(Bin, <>); unescape(<>, Acc) -> unescape(Bin, <>); unescape(<<>>, Acc) -> Acc. unescape_byte(H, L) -> int(H) * 16 + int(L). int(C) when $0 =< C, C =< $9 -> C - $0; int(C) when $A =< C, C =< $F -> C - $A + 10; int(C) when $a =< C, C =< $f -> C - $a + 10. %% %% decode utf8 (TODO: utf8 for binaries) decode(<>, Acc) when H >= 16#C0 -> decode(Rest, <>); decode(<>, Acc) -> decode(Rest, <>); decode(<<>>, Acc) -> Acc.