Skip to content

Instantly share code, notes, and snippets.

@betawaffle
Created April 15, 2012 16:31
Show Gist options
  • Save betawaffle/2393706 to your computer and use it in GitHub Desktop.
Save betawaffle/2393706 to your computer and use it in GitHub Desktop.
-type folder(T, Acc) :: fun((T, Acc) -> Acc).
-type byte_folder(Acc) :: folder(byte(), Acc).
-spec foldl_bytes(byte_folder(Acc), Acc, io()) -> Acc.
foldl_bytes(Fun, Acc, Binary) when is_binary(Binary) ->
foldl_binary_bytes(Fun, Acc, Binary);
foldl_bytes(Fun, Acc, IoList) when is_list(IoList) ->
foldl_iolist_bytes(Fun, Acc, IoList).
-spec foldl_binary_bytes(byte_folder(Acc), Acc, binary()) -> Acc.
foldl_binary_bytes(Fun, Acc, <<C:8, Rest/binary>>) ->
foldl_binary_bytes(Fun, Fun(C, Acc), Rest);
foldl_binary_bytes( _, Acc, <<>>) -> Acc.
-spec foldl_iolist_bytes(byte_folder(Acc), Acc, iolist()) -> Acc.
foldl_iolist_bytes(Fun, Acc, [Byte|Rest]) when 0 =< Byte, Byte =< 255 ->
foldl_iolist_bytes(Fun, Fun(Byte, Acc), Rest);
foldl_iolist_bytes(Fun, Acc, [Other|Rest]) ->
foldl_iolist_bytes(Fun, foldl_bytes(Fun, Acc, Other), Rest);
foldl_iolist_bytes( _, Acc, []) -> Acc.
-spec percent_encode_byte(byte(), binary()) -> binary().
percent_encode_byte(C, Acc)
when $0 =< C, C =< $9;
$a =< C, C =< $z;
$A =< C, C =< $Z;
$- == C; C == $.;
$_ == C; C == $~ ->
<<Acc/binary, C>>;
percent_encode_byte(C, Acc) ->
HexA = hex(C band 16#F0 bsr 4),
HexB = hex(C band 16#0F),
<<Acc/binary, $%, HexA, HexB>>.
%% ===================
%% Using foldl_bytes/3
%% ===================
-spec percent_encode(io(), binary()) -> binary().
percent_encode(Io, Acc) ->
Fun = fun percent_encode_byte/2,
foldl_bytes(Fun, Acc, Io).
%% =======================
%% Not using foldl_bytes/3
%% =======================
-spec percent_encode(io(), binary()) -> binary().
percent_encode(Binary, Acc) when is_binary(Binary) ->
percent_encode_binary(Binary, Acc);
percent_encode(IoList, Acc) when is_list(IoList) ->
percent_encode_iolist(IoList, Acc).
-spec percent_encode_binary(binary(), binary()) -> binary().
percent_encode_binary(<<C:8, Rest/binary>>, Acc) ->
percent_encode_binary(Rest, percent_encode_byte(C, Acc));
percent_encode_binary(<<>>, Acc) -> Acc.
-spec percent_encode_iolist(iolist(), binary()) -> binary().
percent_encode_iolist([Byte|Rest], Acc) when 0 =< Byte, Byte =< 255 ->
percent_encode_iolist(Rest, percent_encode_byte(Byte, Acc));
percent_encode_iolist([Io|Rest], Acc) ->
percent_encode_iolist(Rest, percent_encode(Io, Acc));
percent_encode_iolist([], Acc) -> Acc.
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment