|
@@ -1,174 +0,0 @@
|
|
|
--module(nitro_conv).
|
|
|
-%%-author('Maxim Sokhatsky').
|
|
|
-
|
|
|
-%% N2O Formatter: JSON, BERT
|
|
|
-
|
|
|
--compile(export_all).
|
|
|
--include_lib("nitro/include/nitro.hrl").
|
|
|
-
|
|
|
-
|
|
|
-%% URL encode/decode
|
|
|
-
|
|
|
--define(PERCENT, 37). % $\%
|
|
|
--define(FULLSTOP, 46). % $\.
|
|
|
--define(IS_HEX(C), ((C >= $0 andalso C =< $9) orelse
|
|
|
- (C >= $a andalso C =< $f) orelse
|
|
|
- (C >= $A andalso C =< $F))).
|
|
|
--define(QS_SAFE(C), ((C >= $a andalso C =< $z) orelse
|
|
|
- (C >= $A andalso C =< $Z) orelse
|
|
|
- (C >= $0 andalso C =< $9) orelse
|
|
|
- (C =:= ?FULLSTOP orelse C =:= $- orelse
|
|
|
- C =:= $~ orelse C =:= $_))).
|
|
|
-
|
|
|
-url_encode(Atom) when erlang:is_atom(Atom) ->
|
|
|
- url_encode(erlang:atom_to_list(Atom));
|
|
|
-url_encode(Int) when erlang:is_integer(Int) ->
|
|
|
- url_encode(erlang:integer_to_list(Int));
|
|
|
-url_encode(Bin) when erlang:is_binary(Bin) ->
|
|
|
- url_encode(erlang:binary_to_list(Bin));
|
|
|
-url_encode(String) ->
|
|
|
- url_encode(String, []).
|
|
|
-
|
|
|
-url_encode([], Acc) ->
|
|
|
- lists:reverse(Acc);
|
|
|
-url_encode([C | Rest], Acc) when ?QS_SAFE(C) ->
|
|
|
- url_encode(Rest, [C | Acc]);
|
|
|
-url_encode([$\s | Rest], Acc) ->
|
|
|
- url_encode(Rest, [$+ | Acc]);
|
|
|
-url_encode([C | Rest], Acc) ->
|
|
|
- <<Hi:4, Lo:4>> = <<C>>,
|
|
|
- url_encode(Rest, [digit(Lo), digit(Hi), ?PERCENT | Acc]).
|
|
|
-
|
|
|
-url_decode(Binary) when erlang:is_binary(Binary) ->
|
|
|
- url_decode(erlang:binary_to_list(Binary));
|
|
|
-url_decode(String) -> url_decode_h(lists:reverse(String)).
|
|
|
-
|
|
|
-unhexdigit(C) when C >= $0, C =< $9 ->
|
|
|
- C - $0;
|
|
|
-unhexdigit(C) when C >= $a, C =< $f ->
|
|
|
- C - $a + 10;
|
|
|
-unhexdigit(C) when C >= $A, C =< $F ->
|
|
|
- C - $A + 10.
|
|
|
-
|
|
|
-url_decode_h(S) -> url_decode_h(S, []).
|
|
|
-
|
|
|
-url_decode_h([], Acc) -> Acc;
|
|
|
-url_decode_h([$+ | Rest], Acc) ->
|
|
|
- url_decode_h(Rest, [$\s | Acc]);
|
|
|
-url_decode_h([Lo, Hi, ?PERCENT | Rest], Acc) when ?IS_HEX(Lo), ?IS_HEX(Hi) ->
|
|
|
- url_decode_h(Rest, [(unhexdigit(Lo) bor (unhexdigit(Hi) bsl 4)) | Acc]);
|
|
|
-url_decode_h([C | Rest], Acc) -> url_decode_h(Rest, [C | Acc]).
|
|
|
-
|
|
|
-
|
|
|
-%% JavaScript escape
|
|
|
-
|
|
|
-js_escape(undefined) -> [];
|
|
|
-js_escape(Value) when erlang:is_list(Value) ->
|
|
|
- erlang:binary_to_list( js_escape( erlang:iolist_to_binary(Value) ) );
|
|
|
-js_escape(Value) -> js_escape(Value, <<>>).
|
|
|
-
|
|
|
-js_escape(<<"\\", Rest/binary>>, Acc) -> %"
|
|
|
- js_escape(Rest, <<Acc/binary, "\\\\">>); %"
|
|
|
-js_escape(<<"\r", Rest/binary>>, Acc) ->
|
|
|
- js_escape(Rest, <<Acc/binary, "\\r">>);
|
|
|
-js_escape(<<"\n", Rest/binary>>, Acc) ->
|
|
|
- js_escape(Rest, <<Acc/binary, "\\n">>);
|
|
|
-js_escape(<<"\"", Rest/binary>>, Acc) ->
|
|
|
- js_escape(Rest, <<Acc/binary, "\\\"">>);
|
|
|
-js_escape(<<"'", Rest/binary>>, Acc) ->
|
|
|
- js_escape(Rest, <<Acc/binary, "\\'">>);
|
|
|
-js_escape(<<"`", Rest/binary>>, Acc) ->
|
|
|
- js_escape(Rest, <<Acc/binary, "\\`">>);
|
|
|
-js_escape(<<"<script", Rest/binary>>, Acc) ->
|
|
|
- js_escape(Rest, <<Acc/binary, "<script">>);
|
|
|
-js_escape(<<"script>", Rest/binary>>, Acc) ->
|
|
|
- js_escape(Rest, <<Acc/binary, "script>">>);
|
|
|
-js_escape(<<C, Rest/binary>>, Acc) ->
|
|
|
- js_escape(Rest, <<Acc/binary, C>>);
|
|
|
-js_escape(<<>>, Acc) -> Acc.
|
|
|
-
|
|
|
-
|
|
|
-%% JOIN
|
|
|
-
|
|
|
-%% join(List, Delimiter)
|
|
|
-join([], _) -> [];
|
|
|
-join([Item], _Delim) -> [Item];
|
|
|
-join([Item|Items], Delim) ->
|
|
|
- [Item, Delim | join(Items, Delim)].
|
|
|
-
|
|
|
-
|
|
|
-%% Fast HEX
|
|
|
-
|
|
|
-%digit(0) -> $0;
|
|
|
-%digit(1) -> $1;
|
|
|
-%digit(2) -> $2;
|
|
|
-%digit(3) -> $3;
|
|
|
-%digit(4) -> $4;
|
|
|
-%digit(5) -> $5;
|
|
|
-%digit(6) -> $6;
|
|
|
-%digit(7) -> $7;
|
|
|
-%digit(8) -> $8;
|
|
|
-%digit(9) -> $9;
|
|
|
-%digit(10) -> $a;
|
|
|
-%digit(11) -> $b;
|
|
|
-%digit(12) -> $c;
|
|
|
-%digit(13) -> $d;
|
|
|
-%digit(14) -> $e;
|
|
|
-%digit(15) -> $f.
|
|
|
-digit(X) when X >= 0 andalso X =< 9 -> X + 48;
|
|
|
-digit(X) when X >= 10 andalso X =< 15 -> X + 87.
|
|
|
-
|
|
|
-hex(Bin) ->
|
|
|
- << << (digit(A1)), (digit(A2)) >> || <<A1:4, A2:4>> <= Bin >>.
|
|
|
-unhex(Hex) ->
|
|
|
- << << (erlang:list_to_integer([H1, H2], 16)) >> || <<H1, H2>> <= Hex >>.
|
|
|
-
|
|
|
-
|
|
|
-f(S) -> f(S, []).
|
|
|
-
|
|
|
-f(S, Args) -> lists:flatten(io_lib:format(S, Args)).
|
|
|
-
|
|
|
-
|
|
|
-replace([], _, _) -> [];
|
|
|
-replace(String, S1, S2) when erlang:is_list(String), erlang:is_list(S1), erlang:is_list(S2) ->
|
|
|
- Length = erlang:length(S1),
|
|
|
- case string:substr(String, 1, Length) of
|
|
|
- S1 -> S2 ++ replace(string:substr(String, Length + 1), S1, S2);
|
|
|
- _ -> [hd(String)|replace(tl(String), S1, S2)]
|
|
|
- end.
|
|
|
-
|
|
|
-
|
|
|
-coalesce({_, Y}) -> Y;
|
|
|
-coalesce(false) -> undefined;
|
|
|
-coalesce([]) -> undefined;
|
|
|
-coalesce([H]) -> H;
|
|
|
-coalesce([undefined|T]) -> coalesce(T);
|
|
|
-coalesce([[]|T]) -> coalesce(T);
|
|
|
-coalesce([H|_]) -> H.
|
|
|
-
|
|
|
-
|
|
|
-indexof(Key, Fields) -> indexof(Key, Fields, 2).
|
|
|
-
|
|
|
-indexof(_, [], _) -> undefined;
|
|
|
-indexof(Key, [Key|_], N) -> N;
|
|
|
-indexof(Key, [_|T], N) -> indexof(Key, T, N + 1).
|
|
|
-
|
|
|
-
|
|
|
-config(App, Key, Default) -> application:get_env(App, Key, Default).
|
|
|
-
|
|
|
-os_env(Key) -> os_env(Key, "").
|
|
|
-
|
|
|
-os_env(Key, Default) ->
|
|
|
- case os:getenv(Key) of
|
|
|
- false -> Default;
|
|
|
- V -> V
|
|
|
- end.
|
|
|
-
|
|
|
-%% base64 encode/decode
|
|
|
-pickle(Data) -> base64:encode(erlang:term_to_binary({Data, os:timestamp()}, [compressed])).
|
|
|
-depickle(PickledData) ->
|
|
|
- try {Data, _PickleTime} = erlang:binary_to_term(base64:decode(nitro:to_binary(PickledData))),
|
|
|
- Data
|
|
|
- catch _:_ -> undefined
|
|
|
- end.
|
|
|
-
|