aboutsummaryrefslogtreecommitdiff
path: root/src/jlib.erl
diff options
context:
space:
mode:
Diffstat (limited to 'src/jlib.erl')
-rw-r--r--src/jlib.erl135
1 files changed, 126 insertions, 9 deletions
diff --git a/src/jlib.erl b/src/jlib.erl
index 1ee2e4ffa..de75ca0a9 100644
--- a/src/jlib.erl
+++ b/src/jlib.erl
@@ -5,7 +5,7 @@
%%% Created : 23 Nov 2002 by Alexey Shchepin <alexey@process-one.net>
%%%
%%%
-%%% ejabberd, Copyright (C) 2002-2008 Process-one
+%%% ejabberd, Copyright (C) 2002-2009 ProcessOne
%%%
%%% This program is free software; you can redistribute it and/or
%%% modify it under the terms of the GNU General Public License as
@@ -16,7 +16,7 @@
%%% but WITHOUT ANY WARRANTY; without even the implied warranty of
%%% MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
%%% General Public License for more details.
-%%%
+%%%
%%% You should have received a copy of the GNU General Public License
%%% along with this program; if not, write to the Free Software
%%% Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA
@@ -34,6 +34,8 @@
make_correct_from_to_attrs/3,
replace_from_to_attrs/3,
replace_from_to/3,
+ replace_from_attrs/2,
+ replace_from/2,
remove_attr/2,
make_jid/3,
make_jid/1,
@@ -53,13 +55,19 @@
is_iq_request_type/1,
iq_to_xml/1,
parse_xdata_submit/1,
- timestamp_to_iso/1,
- timestamp_to_xml/1,
+ timestamp_to_iso/1, % TODO: Remove once XEP-0091 is Obsolete
+ timestamp_to_iso/2,
+ timestamp_to_xml/4,
+ timestamp_to_xml/1, % TODO: Remove once XEP-0091 is Obsolete
now_to_utc_string/1,
now_to_local_string/1,
datetime_string_to_timestamp/1,
decode_base64/1,
- encode_base64/1]).
+ encode_base64/1,
+ ip_to_list/1,
+ rsm_encode/1,
+ rsm_encode/2,
+ rsm_decode/1]).
-include("jlib.hrl").
@@ -152,6 +160,13 @@ replace_from_to(From, To, {xmlelement, Name, Attrs, Els}) ->
Attrs),
{xmlelement, Name, NewAttrs, Els}.
+replace_from_attrs(From, Attrs) ->
+ Attrs1 = lists:keydelete("from", 1, Attrs),
+ [{"from", From} | Attrs1].
+
+replace_from(From, {xmlelement, Name, Attrs, Els}) ->
+ NewAttrs = replace_from_attrs(jlib:jid_to_string(From), Attrs),
+ {xmlelement, Name, NewAttrs, Els}.
remove_attr(Attr, {xmlelement, Name, Attrs, Els}) ->
NewAttrs = lists:keydelete(Attr, 1, Attrs),
@@ -474,15 +489,111 @@ parse_xdata_values([{xmlelement, Name, _Attrs, SubEls} | Els], Res) ->
parse_xdata_values([_ | Els], Res) ->
parse_xdata_values(Els, Res).
+rsm_decode(#iq{sub_el=SubEl})->
+ rsm_decode(SubEl);
+rsm_decode({xmlelement, _,_,_}=SubEl)->
+ case xml:get_subtag(SubEl,"set") of
+ false ->
+ none;
+ {xmlelement, "set", _Attrs, SubEls}->
+ lists:foldl(fun rsm_parse_element/2, #rsm_in{}, SubEls)
+ end.
+
+rsm_parse_element({xmlelement, "max",[], _}=Elem, RsmIn)->
+ CountStr = xml:get_tag_cdata(Elem),
+ {Count, _} = string:to_integer(CountStr),
+ RsmIn#rsm_in{max=Count};
+
+rsm_parse_element({xmlelement, "before", [], _}=Elem, RsmIn)->
+ UID = xml:get_tag_cdata(Elem),
+ RsmIn#rsm_in{direction=before, id=UID};
+
+rsm_parse_element({xmlelement, "after", [], _}=Elem, RsmIn)->
+ UID = xml:get_tag_cdata(Elem),
+ RsmIn#rsm_in{direction=aft, id=UID};
+
+rsm_parse_element({xmlelement, "index",[], _}=Elem, RsmIn)->
+ IndexStr = xml:get_tag_cdata(Elem),
+ {Index, _} = string:to_integer(IndexStr),
+ RsmIn#rsm_in{index=Index};
+
+
+rsm_parse_element(_, RsmIn)->
+ RsmIn.
+
+rsm_encode(#iq{sub_el=SubEl}=IQ,RsmOut)->
+ Set = {xmlelement, "set", [{"xmlns", ?NS_RSM}],
+ lists:reverse(rsm_encode_out(RsmOut))},
+ {xmlelement, Name, Attrs, SubEls} = SubEl,
+ New = {xmlelement, Name, Attrs, [Set | SubEls]},
+ IQ#iq{sub_el=New}.
+
+rsm_encode(none)->
+ [];
+rsm_encode(RsmOut)->
+ [{xmlelement, "set", [{"xmlns", ?NS_RSM}], lists:reverse(rsm_encode_out(RsmOut))}].
+rsm_encode_out(#rsm_out{count=Count, index=Index, first=First, last=Last})->
+ El = rsm_encode_first(First, Index, []),
+ El2 = rsm_encode_last(Last,El),
+ rsm_encode_count(Count, El2).
+
+rsm_encode_first(undefined, undefined, Arr) ->
+ Arr;
+rsm_encode_first(First, undefined, Arr) ->
+ [{xmlelement, "first",[], [{xmlcdata, First}]}|Arr];
+rsm_encode_first(First, Index, Arr) ->
+ [{xmlelement, "first",[{"index", i2l(Index)}], [{xmlcdata, First}]}|Arr].
+
+rsm_encode_last(undefined, Arr) -> Arr;
+rsm_encode_last(Last, Arr) ->
+ [{xmlelement, "last",[], [{xmlcdata, Last}]}|Arr].
+
+rsm_encode_count(undefined, Arr)-> Arr;
+rsm_encode_count(Count, Arr)->
+ [{xmlelement, "count",[], [{xmlcdata, i2l(Count)}]} | Arr].
+
+i2l(I) when is_integer(I) -> integer_to_list(I);
+i2l(L) when is_list(L) -> L.
+
+%% Timezone = utc | {Hours, Minutes}
+%% Hours = integer()
+%% Minutes = integer()
+timestamp_to_iso({{Year, Month, Day}, {Hour, Minute, Second}}, Timezone) ->
+ Timestamp_string =
+ lists:flatten(
+ io_lib:format("~4..0w-~2..0w-~2..0wT~2..0w:~2..0w:~2..0w",
+ [Year, Month, Day, Hour, Minute, Second])),
+ Timezone_string =
+ case Timezone of
+ utc -> "Z";
+ {TZh, TZm} ->
+ Sign = case TZh >= 0 of
+ true -> "+";
+ false -> "-"
+ end,
+ io_lib:format("~s~2..0w:~2..0w", [Sign, abs(TZh),TZm])
+ end,
+ {Timestamp_string, Timezone_string}.
timestamp_to_iso({{Year, Month, Day}, {Hour, Minute, Second}}) ->
lists:flatten(
io_lib:format("~4..0w~2..0w~2..0wT~2..0w:~2..0w:~2..0w",
[Year, Month, Day, Hour, Minute, Second])).
+timestamp_to_xml(DateTime, Timezone, FromJID, Desc) ->
+ {T_string, Tz_string} = timestamp_to_iso(DateTime, Timezone),
+ Text = [{xmlcdata, Desc}],
+ From = jlib:jid_to_string(FromJID),
+ {xmlelement, "delay",
+ [{"xmlns", ?NS_DELAY},
+ {"from", From},
+ {"stamp", T_string ++ Tz_string}],
+ Text}.
+
+%% TODO: Remove this function once XEP-0091 is Obsolete
timestamp_to_xml({{Year, Month, Day}, {Hour, Minute, Second}}) ->
{xmlelement, "x",
- [{"xmlns", ?NS_DELAY},
+ [{"xmlns", ?NS_DELAY91},
{"stamp", lists:flatten(
io_lib:format("~4..0w~2..0w~2..0wT~2..0w:~2..0w:~2..0w",
[Year, Month, Day, Hour, Minute, Second]))}],
@@ -624,7 +735,7 @@ decode1_base64([Sextet1,Sextet2,$=,$=|Rest]) ->
(d(Sextet1) bsl 18) bor
(d(Sextet2) bsl 12),
Octet1=Bits2x6 bsr 16,
- [Octet1|decode_base64(Rest)];
+ [Octet1|decode1_base64(Rest)];
decode1_base64([Sextet1,Sextet2,Sextet3,$=|Rest]) ->
Bits3x6=
(d(Sextet1) bsl 18) bor
@@ -632,7 +743,7 @@ decode1_base64([Sextet1,Sextet2,Sextet3,$=|Rest]) ->
(d(Sextet3) bsl 6),
Octet1=Bits3x6 bsr 16,
Octet2=(Bits3x6 bsr 8) band 16#ff,
- [Octet1,Octet2|decode_base64(Rest)];
+ [Octet1,Octet2|decode1_base64(Rest)];
decode1_base64([Sextet1,Sextet2,Sextet3,Sextet4|Rest]) ->
Bits4x6=
(d(Sextet1) bsl 18) bor
@@ -642,7 +753,7 @@ decode1_base64([Sextet1,Sextet2,Sextet3,Sextet4|Rest]) ->
Octet1=Bits4x6 bsr 16,
Octet2=(Bits4x6 bsr 8) band 16#ff,
Octet3=Bits4x6 band 16#ff,
- [Octet1,Octet2,Octet3|decode_base64(Rest)];
+ [Octet1,Octet2,Octet3|decode1_base64(Rest)];
decode1_base64(_CatchAll) ->
"".
@@ -676,3 +787,9 @@ e(X) when X>51, X<62 -> X-4;
e(62) -> $+;
e(63) -> $/;
e(X) -> exit({bad_encode_base64_token, X}).
+
+%% Convert Erlang inet IP to list
+ip_to_list({IP, _Port}) ->
+ ip_to_list(IP);
+ip_to_list({A,B,C,D}) ->
+ lists:flatten(io_lib:format("~w.~w.~w.~w",[A,B,C,D])).