Welcome to mirror list, hosted at ThFree Co, Russian Federation.

github.com/processone/ejabberd.git - Unnamed repository; edit this file 'description' to name the repository.
summaryrefslogtreecommitdiff
path: root/tools
diff options
context:
space:
mode:
authorEvgeniy Khramtsov <ekhramtsov@process-one.net>2015-06-22 16:56:08 +0300
committerEvgeniy Khramtsov <ekhramtsov@process-one.net>2015-06-22 16:56:08 +0300
commit83cce468a573d3ca58a0c6653a2ccc17c7b4dbc3 (patch)
tree0e8bffc0327e389ab9eda4b944d85b35fd1e90eb /tools
parent66310788848ef185f3831648b2abf67ab6ded7fa (diff)
Add MAM (XEP-0313) support
Diffstat (limited to 'tools')
-rw-r--r--tools/xmpp_codec.erl1200
-rw-r--r--tools/xmpp_codec.hrl35
-rw-r--r--tools/xmpp_codec.spec150
3 files changed, 1385 insertions, 0 deletions
diff --git a/tools/xmpp_codec.erl b/tools/xmpp_codec.erl
index 187098abc..0dbc62808 100644
--- a/tools/xmpp_codec.erl
+++ b/tools/xmpp_codec.erl
@@ -73,6 +73,65 @@ decode({xmlel, _name, _attrs, _} = _el, Opts) ->
{<<"forwarded">>, <<"urn:xmpp:forward:0">>} ->
decode_forwarded(<<"urn:xmpp:forward:0">>, IgnoreEls,
_el);
+ {<<"fin">>, <<"urn:xmpp:mam:0">>} ->
+ decode_mam_fin(<<"urn:xmpp:mam:0">>, IgnoreEls, _el);
+ {<<"prefs">>, <<"urn:xmpp:mam:0">>} ->
+ decode_mam_prefs(<<"urn:xmpp:mam:0">>, IgnoreEls, _el);
+ {<<"prefs">>, <<"urn:xmpp:mam:tmp">>} ->
+ decode_mam_prefs(<<"urn:xmpp:mam:tmp">>, IgnoreEls,
+ _el);
+ {<<"always">>, <<"urn:xmpp:mam:tmp">>} ->
+ decode_mam_always(<<"urn:xmpp:mam:tmp">>, IgnoreEls,
+ _el);
+ {<<"never">>, <<"urn:xmpp:mam:tmp">>} ->
+ decode_mam_never(<<"urn:xmpp:mam:tmp">>, IgnoreEls,
+ _el);
+ {<<"jid">>, <<"urn:xmpp:mam:tmp">>} ->
+ decode_mam_jid(<<"urn:xmpp:mam:tmp">>, IgnoreEls, _el);
+ {<<"result">>, <<"urn:xmpp:mam:0">>} ->
+ decode_mam_result(<<"urn:xmpp:mam:0">>, IgnoreEls, _el);
+ {<<"result">>, <<"urn:xmpp:mam:tmp">>} ->
+ decode_mam_result(<<"urn:xmpp:mam:tmp">>, IgnoreEls,
+ _el);
+ {<<"archived">>, <<"urn:xmpp:mam:tmp">>} ->
+ decode_mam_archived(<<"urn:xmpp:mam:tmp">>, IgnoreEls,
+ _el);
+ {<<"query">>, <<"urn:xmpp:mam:0">>} ->
+ decode_mam_query(<<"urn:xmpp:mam:0">>, IgnoreEls, _el);
+ {<<"query">>, <<"urn:xmpp:mam:tmp">>} ->
+ decode_mam_query(<<"urn:xmpp:mam:tmp">>, IgnoreEls,
+ _el);
+ {<<"with">>, <<"urn:xmpp:mam:tmp">>} ->
+ decode_mam_with(<<"urn:xmpp:mam:tmp">>, IgnoreEls, _el);
+ {<<"end">>, <<"urn:xmpp:mam:tmp">>} ->
+ decode_mam_end(<<"urn:xmpp:mam:tmp">>, IgnoreEls, _el);
+ {<<"start">>, <<"urn:xmpp:mam:tmp">>} ->
+ decode_mam_start(<<"urn:xmpp:mam:tmp">>, IgnoreEls,
+ _el);
+ {<<"set">>, <<"http://jabber.org/protocol/rsm">>} ->
+ decode_rsm_set(<<"http://jabber.org/protocol/rsm">>,
+ IgnoreEls, _el);
+ {<<"first">>, <<"http://jabber.org/protocol/rsm">>} ->
+ decode_rsm_first(<<"http://jabber.org/protocol/rsm">>,
+ IgnoreEls, _el);
+ {<<"max">>, <<"http://jabber.org/protocol/rsm">>} ->
+ decode_rsm_max(<<"http://jabber.org/protocol/rsm">>,
+ IgnoreEls, _el);
+ {<<"index">>, <<"http://jabber.org/protocol/rsm">>} ->
+ decode_rsm_index(<<"http://jabber.org/protocol/rsm">>,
+ IgnoreEls, _el);
+ {<<"count">>, <<"http://jabber.org/protocol/rsm">>} ->
+ decode_rsm_count(<<"http://jabber.org/protocol/rsm">>,
+ IgnoreEls, _el);
+ {<<"last">>, <<"http://jabber.org/protocol/rsm">>} ->
+ decode_rsm_last(<<"http://jabber.org/protocol/rsm">>,
+ IgnoreEls, _el);
+ {<<"before">>, <<"http://jabber.org/protocol/rsm">>} ->
+ decode_rsm_before(<<"http://jabber.org/protocol/rsm">>,
+ IgnoreEls, _el);
+ {<<"after">>, <<"http://jabber.org/protocol/rsm">>} ->
+ decode_rsm_after(<<"http://jabber.org/protocol/rsm">>,
+ IgnoreEls, _el);
{<<"x">>, <<"http://jabber.org/protocol/muc">>} ->
decode_muc(<<"http://jabber.org/protocol/muc">>,
IgnoreEls, _el);
@@ -1038,6 +1097,36 @@ is_known_tag({xmlel, _name, _attrs, _} = _el) ->
{<<"enable">>, <<"urn:xmpp:carbons:2">>} -> true;
{<<"disable">>, <<"urn:xmpp:carbons:2">>} -> true;
{<<"forwarded">>, <<"urn:xmpp:forward:0">>} -> true;
+ {<<"fin">>, <<"urn:xmpp:mam:0">>} -> true;
+ {<<"prefs">>, <<"urn:xmpp:mam:0">>} -> true;
+ {<<"prefs">>, <<"urn:xmpp:mam:tmp">>} -> true;
+ {<<"always">>, <<"urn:xmpp:mam:tmp">>} -> true;
+ {<<"never">>, <<"urn:xmpp:mam:tmp">>} -> true;
+ {<<"jid">>, <<"urn:xmpp:mam:tmp">>} -> true;
+ {<<"result">>, <<"urn:xmpp:mam:0">>} -> true;
+ {<<"result">>, <<"urn:xmpp:mam:tmp">>} -> true;
+ {<<"archived">>, <<"urn:xmpp:mam:tmp">>} -> true;
+ {<<"query">>, <<"urn:xmpp:mam:0">>} -> true;
+ {<<"query">>, <<"urn:xmpp:mam:tmp">>} -> true;
+ {<<"with">>, <<"urn:xmpp:mam:tmp">>} -> true;
+ {<<"end">>, <<"urn:xmpp:mam:tmp">>} -> true;
+ {<<"start">>, <<"urn:xmpp:mam:tmp">>} -> true;
+ {<<"set">>, <<"http://jabber.org/protocol/rsm">>} ->
+ true;
+ {<<"first">>, <<"http://jabber.org/protocol/rsm">>} ->
+ true;
+ {<<"max">>, <<"http://jabber.org/protocol/rsm">>} ->
+ true;
+ {<<"index">>, <<"http://jabber.org/protocol/rsm">>} ->
+ true;
+ {<<"count">>, <<"http://jabber.org/protocol/rsm">>} ->
+ true;
+ {<<"last">>, <<"http://jabber.org/protocol/rsm">>} ->
+ true;
+ {<<"before">>, <<"http://jabber.org/protocol/rsm">>} ->
+ true;
+ {<<"after">>, <<"http://jabber.org/protocol/rsm">>} ->
+ true;
{<<"x">>, <<"http://jabber.org/protocol/muc">>} -> true;
{<<"query">>,
<<"http://jabber.org/protocol/muc#admin">>} ->
@@ -1978,6 +2067,24 @@ encode({muc_admin, _} = Query) ->
encode({muc, _, _} = X) ->
encode_muc(X,
[{<<"xmlns">>, <<"http://jabber.org/protocol/muc">>}]);
+encode({rsm_first, _, _} = First) ->
+ encode_rsm_first(First,
+ [{<<"xmlns">>, <<"http://jabber.org/protocol/rsm">>}]);
+encode({rsm_set, _, _, _, _, _, _, _} = Set) ->
+ encode_rsm_set(Set,
+ [{<<"xmlns">>, <<"http://jabber.org/protocol/rsm">>}]);
+encode({mam_query, _, _, _, _, _, _, _} = Query) ->
+ encode_mam_query(Query, []);
+encode({mam_archived, _, _} = Archived) ->
+ encode_mam_archived(Archived,
+ [{<<"xmlns">>, <<"urn:xmpp:mam:tmp">>}]);
+encode({mam_result, _, _, _, _} = Result) ->
+ encode_mam_result(Result, []);
+encode({mam_prefs, _, _, _, _} = Prefs) ->
+ encode_mam_prefs(Prefs, []);
+encode({mam_fin, _, _} = Fin) ->
+ encode_mam_fin(Fin,
+ [{<<"xmlns">>, <<"urn:xmpp:mam:0">>}]);
encode({forwarded, _, _} = Forwarded) ->
encode_forwarded(Forwarded,
[{<<"xmlns">>, <<"urn:xmpp:forward:0">>}]);
@@ -2196,6 +2303,12 @@ get_ns({muc_admin, _}) ->
<<"http://jabber.org/protocol/muc#admin">>;
get_ns({muc, _, _}) ->
<<"http://jabber.org/protocol/muc">>;
+get_ns({rsm_first, _, _}) ->
+ <<"http://jabber.org/protocol/rsm">>;
+get_ns({rsm_set, _, _, _, _, _, _, _}) ->
+ <<"http://jabber.org/protocol/rsm">>;
+get_ns({mam_archived, _, _}) -> <<"urn:xmpp:mam:tmp">>;
+get_ns({mam_fin, _, _}) -> <<"urn:xmpp:mam:0">>;
get_ns({forwarded, _, _}) -> <<"urn:xmpp:forward:0">>;
get_ns({carbons_disable}) -> <<"urn:xmpp:carbons:2">>;
get_ns({carbons_enable}) -> <<"urn:xmpp:carbons:2">>;
@@ -2384,6 +2497,15 @@ pp(muc_item, 7) ->
pp(muc_actor, 2) -> [jid, nick];
pp(muc_admin, 1) -> [items];
pp(muc, 2) -> [history, password];
+pp(rsm_first, 2) -> [index, data];
+pp(rsm_set, 7) ->
+ ['after', before, count, first, index, last, max];
+pp(mam_query, 7) ->
+ [xmlns, id, start, 'end', with, rsm, xdata];
+pp(mam_archived, 2) -> [by, id];
+pp(mam_result, 4) -> [xmlns, queryid, id, sub_els];
+pp(mam_prefs, 4) -> [xmlns, default, always, never];
+pp(mam_fin, 2) -> [id, rsm];
pp(forwarded, 2) -> [delay, sub_els];
pp(carbons_disable, 0) -> [];
pp(carbons_enable, 0) -> [];
@@ -3583,6 +3705,1084 @@ encode_forwarded({forwarded, Delay, __Els},
[{<<"xmlns">>, <<"urn:xmpp:delay">>}])
| _acc].
+decode_mam_fin(__TopXMLNS, __IgnoreEls,
+ {xmlel, <<"fin">>, _attrs, _els}) ->
+ Rsm = decode_mam_fin_els(__TopXMLNS, __IgnoreEls, _els,
+ undefined),
+ Id = decode_mam_fin_attrs(__TopXMLNS, _attrs,
+ undefined),
+ {mam_fin, Id, Rsm}.
+
+decode_mam_fin_els(__TopXMLNS, __IgnoreEls, [], Rsm) ->
+ Rsm;
+decode_mam_fin_els(__TopXMLNS, __IgnoreEls,
+ [{xmlel, <<"set">>, _attrs, _} = _el | _els], Rsm) ->
+ _xmlns = get_attr(<<"xmlns">>, _attrs),
+ if _xmlns == <<"http://jabber.org/protocol/rsm">> ->
+ decode_mam_fin_els(__TopXMLNS, __IgnoreEls, _els,
+ decode_rsm_set(_xmlns, __IgnoreEls, _el));
+ true ->
+ decode_mam_fin_els(__TopXMLNS, __IgnoreEls, _els, Rsm)
+ end;
+decode_mam_fin_els(__TopXMLNS, __IgnoreEls, [_ | _els],
+ Rsm) ->
+ decode_mam_fin_els(__TopXMLNS, __IgnoreEls, _els, Rsm).
+
+decode_mam_fin_attrs(__TopXMLNS,
+ [{<<"queryid">>, _val} | _attrs], _Id) ->
+ decode_mam_fin_attrs(__TopXMLNS, _attrs, _val);
+decode_mam_fin_attrs(__TopXMLNS, [_ | _attrs], Id) ->
+ decode_mam_fin_attrs(__TopXMLNS, _attrs, Id);
+decode_mam_fin_attrs(__TopXMLNS, [], Id) ->
+ decode_mam_fin_attr_queryid(__TopXMLNS, Id).
+
+encode_mam_fin({mam_fin, Id, Rsm}, _xmlns_attrs) ->
+ _els = lists:reverse('encode_mam_fin_$rsm'(Rsm, [])),
+ _attrs = encode_mam_fin_attr_queryid(Id, _xmlns_attrs),
+ {xmlel, <<"fin">>, _attrs, _els}.
+
+'encode_mam_fin_$rsm'(undefined, _acc) -> _acc;
+'encode_mam_fin_$rsm'(Rsm, _acc) ->
+ [encode_rsm_set(Rsm,
+ [{<<"xmlns">>, <<"http://jabber.org/protocol/rsm">>}])
+ | _acc].
+
+decode_mam_fin_attr_queryid(__TopXMLNS, undefined) ->
+ undefined;
+decode_mam_fin_attr_queryid(__TopXMLNS, _val) -> _val.
+
+encode_mam_fin_attr_queryid(undefined, _acc) -> _acc;
+encode_mam_fin_attr_queryid(_val, _acc) ->
+ [{<<"queryid">>, _val} | _acc].
+
+decode_mam_prefs(__TopXMLNS, __IgnoreEls,
+ {xmlel, <<"prefs">>, _attrs, _els}) ->
+ {Never, Always} = decode_mam_prefs_els(__TopXMLNS,
+ __IgnoreEls, _els, [], []),
+ {Default, Xmlns} = decode_mam_prefs_attrs(__TopXMLNS,
+ _attrs, undefined, undefined),
+ {mam_prefs, Xmlns, Default, Always, Never}.
+
+decode_mam_prefs_els(__TopXMLNS, __IgnoreEls, [], Never,
+ Always) ->
+ {Never, Always};
+decode_mam_prefs_els(__TopXMLNS, __IgnoreEls,
+ [{xmlel, <<"always">>, _attrs, _} = _el | _els], Never,
+ Always) ->
+ _xmlns = get_attr(<<"xmlns">>, _attrs),
+ if _xmlns == <<>>; _xmlns == __TopXMLNS ->
+ decode_mam_prefs_els(__TopXMLNS, __IgnoreEls, _els,
+ Never,
+ decode_mam_always(__TopXMLNS, __IgnoreEls,
+ _el));
+ true ->
+ decode_mam_prefs_els(__TopXMLNS, __IgnoreEls, _els,
+ Never, Always)
+ end;
+decode_mam_prefs_els(__TopXMLNS, __IgnoreEls,
+ [{xmlel, <<"never">>, _attrs, _} = _el | _els], Never,
+ Always) ->
+ _xmlns = get_attr(<<"xmlns">>, _attrs),
+ if _xmlns == <<>>; _xmlns == __TopXMLNS ->
+ decode_mam_prefs_els(__TopXMLNS, __IgnoreEls, _els,
+ decode_mam_never(__TopXMLNS, __IgnoreEls, _el),
+ Always);
+ true ->
+ decode_mam_prefs_els(__TopXMLNS, __IgnoreEls, _els,
+ Never, Always)
+ end;
+decode_mam_prefs_els(__TopXMLNS, __IgnoreEls,
+ [_ | _els], Never, Always) ->
+ decode_mam_prefs_els(__TopXMLNS, __IgnoreEls, _els,
+ Never, Always).
+
+decode_mam_prefs_attrs(__TopXMLNS,
+ [{<<"default">>, _val} | _attrs], _Default, Xmlns) ->
+ decode_mam_prefs_attrs(__TopXMLNS, _attrs, _val, Xmlns);
+decode_mam_prefs_attrs(__TopXMLNS,
+ [{<<"xmlns">>, _val} | _attrs], Default, _Xmlns) ->
+ decode_mam_prefs_attrs(__TopXMLNS, _attrs, Default,
+ _val);
+decode_mam_prefs_attrs(__TopXMLNS, [_ | _attrs],
+ Default, Xmlns) ->
+ decode_mam_prefs_attrs(__TopXMLNS, _attrs, Default,
+ Xmlns);
+decode_mam_prefs_attrs(__TopXMLNS, [], Default,
+ Xmlns) ->
+ {decode_mam_prefs_attr_default(__TopXMLNS, Default),
+ decode_mam_prefs_attr_xmlns(__TopXMLNS, Xmlns)}.
+
+encode_mam_prefs({mam_prefs, Xmlns, Default, Always,
+ Never},
+ _xmlns_attrs) ->
+ _els = lists:reverse('encode_mam_prefs_$never'(Never,
+ 'encode_mam_prefs_$always'(Always,
+ []))),
+ _attrs = encode_mam_prefs_attr_xmlns(Xmlns,
+ encode_mam_prefs_attr_default(Default,
+ _xmlns_attrs)),
+ {xmlel, <<"prefs">>, _attrs, _els}.
+
+'encode_mam_prefs_$never'([], _acc) -> _acc;
+'encode_mam_prefs_$never'(Never, _acc) ->
+ [encode_mam_never(Never,
+ [{<<"xmlns">>, <<"urn:xmpp:mam:tmp">>}])
+ | _acc].
+
+'encode_mam_prefs_$always'([], _acc) -> _acc;
+'encode_mam_prefs_$always'(Always, _acc) ->
+ [encode_mam_always(Always,
+ [{<<"xmlns">>, <<"urn:xmpp:mam:tmp">>}])
+ | _acc].
+
+decode_mam_prefs_attr_default(__TopXMLNS, undefined) ->
+ undefined;
+decode_mam_prefs_attr_default(__TopXMLNS, _val) ->
+ case catch dec_enum(_val, [always, never, roster]) of
+ {'EXIT', _} ->
+ erlang:error({xmpp_codec,
+ {bad_attr_value, <<"default">>, <<"prefs">>,
+ __TopXMLNS}});
+ _res -> _res
+ end.
+
+encode_mam_prefs_attr_default(undefined, _acc) -> _acc;
+encode_mam_prefs_attr_default(_val, _acc) ->
+ [{<<"default">>, enc_enum(_val)} | _acc].
+
+decode_mam_prefs_attr_xmlns(__TopXMLNS, undefined) ->
+ undefined;
+decode_mam_prefs_attr_xmlns(__TopXMLNS, _val) -> _val.
+
+encode_mam_prefs_attr_xmlns(undefined, _acc) -> _acc;
+encode_mam_prefs_attr_xmlns(_val, _acc) ->
+ [{<<"xmlns">>, _val} | _acc].
+
+decode_mam_always(__TopXMLNS, __IgnoreEls,
+ {xmlel, <<"always">>, _attrs, _els}) ->
+ Jids = decode_mam_always_els(__TopXMLNS, __IgnoreEls,
+ _els, []),
+ Jids.
+
+decode_mam_always_els(__TopXMLNS, __IgnoreEls, [],
+ Jids) ->
+ lists:reverse(Jids);
+decode_mam_always_els(__TopXMLNS, __IgnoreEls,
+ [{xmlel, <<"jid">>, _attrs, _} = _el | _els], Jids) ->
+ _xmlns = get_attr(<<"xmlns">>, _attrs),
+ if _xmlns == <<>>; _xmlns == __TopXMLNS ->
+ decode_mam_always_els(__TopXMLNS, __IgnoreEls, _els,
+ case decode_mam_jid(__TopXMLNS, __IgnoreEls,
+ _el)
+ of
+ [] -> Jids;
+ _new_el -> [_new_el | Jids]
+ end);
+ true ->
+ decode_mam_always_els(__TopXMLNS, __IgnoreEls, _els,
+ Jids)
+ end;
+decode_mam_always_els(__TopXMLNS, __IgnoreEls,
+ [_ | _els], Jids) ->
+ decode_mam_always_els(__TopXMLNS, __IgnoreEls, _els,
+ Jids).
+
+encode_mam_always(Jids, _xmlns_attrs) ->
+ _els = lists:reverse('encode_mam_always_$jids'(Jids,
+ [])),
+ _attrs = _xmlns_attrs,
+ {xmlel, <<"always">>, _attrs, _els}.
+
+'encode_mam_always_$jids'([], _acc) -> _acc;
+'encode_mam_always_$jids'([Jids | _els], _acc) ->
+ 'encode_mam_always_$jids'(_els,
+ [encode_mam_jid(Jids, []) | _acc]).
+
+decode_mam_never(__TopXMLNS, __IgnoreEls,
+ {xmlel, <<"never">>, _attrs, _els}) ->
+ Jids = decode_mam_never_els(__TopXMLNS, __IgnoreEls,
+ _els, []),
+ Jids.
+
+decode_mam_never_els(__TopXMLNS, __IgnoreEls, [],
+ Jids) ->
+ lists:reverse(Jids);
+decode_mam_never_els(__TopXMLNS, __IgnoreEls,
+ [{xmlel, <<"jid">>, _attrs, _} = _el | _els], Jids) ->
+ _xmlns = get_attr(<<"xmlns">>, _attrs),
+ if _xmlns == <<>>; _xmlns == __TopXMLNS ->
+ decode_mam_never_els(__TopXMLNS, __IgnoreEls, _els,
+ case decode_mam_jid(__TopXMLNS, __IgnoreEls,
+ _el)
+ of
+ [] -> Jids;
+ _new_el -> [_new_el | Jids]
+ end);
+ true ->
+ decode_mam_never_els(__TopXMLNS, __IgnoreEls, _els,
+ Jids)
+ end;
+decode_mam_never_els(__TopXMLNS, __IgnoreEls,
+ [_ | _els], Jids) ->
+ decode_mam_never_els(__TopXMLNS, __IgnoreEls, _els,
+ Jids).
+
+encode_mam_never(Jids, _xmlns_attrs) ->
+ _els = lists:reverse('encode_mam_never_$jids'(Jids,
+ [])),
+ _attrs = _xmlns_attrs,
+ {xmlel, <<"never">>, _attrs, _els}.
+
+'encode_mam_never_$jids'([], _acc) -> _acc;
+'encode_mam_never_$jids'([Jids | _els], _acc) ->
+ 'encode_mam_never_$jids'(_els,
+ [encode_mam_jid(Jids, []) | _acc]).
+
+decode_mam_jid(__TopXMLNS, __IgnoreEls,
+ {xmlel, <<"jid">>, _attrs, _els}) ->
+ Cdata = decode_mam_jid_els(__TopXMLNS, __IgnoreEls,
+ _els, <<>>),
+ Cdata.
+
+decode_mam_jid_els(__TopXMLNS, __IgnoreEls, [],
+ Cdata) ->
+ decode_mam_jid_cdata(__TopXMLNS, Cdata);
+decode_mam_jid_els(__TopXMLNS, __IgnoreEls,
+ [{xmlcdata, _data} | _els], Cdata) ->
+ decode_mam_jid_els(__TopXMLNS, __IgnoreEls, _els,
+ <<Cdata/binary, _data/binary>>);
+decode_mam_jid_els(__TopXMLNS, __IgnoreEls, [_ | _els],
+ Cdata) ->
+ decode_mam_jid_els(__TopXMLNS, __IgnoreEls, _els,
+ Cdata).
+
+encode_mam_jid(Cdata, _xmlns_attrs) ->
+ _els = encode_mam_jid_cdata(Cdata, []),
+ _attrs = _xmlns_attrs,
+ {xmlel, <<"jid">>, _attrs, _els}.
+
+decode_mam_jid_cdata(__TopXMLNS, <<>>) ->
+ erlang:error({xmpp_codec,
+ {missing_cdata, <<>>, <<"jid">>, __TopXMLNS}});
+decode_mam_jid_cdata(__TopXMLNS, _val) ->
+ case catch dec_jid(_val) of
+ {'EXIT', _} ->
+ erlang:error({xmpp_codec,
+ {bad_cdata_value, <<>>, <<"jid">>, __TopXMLNS}});
+ _res -> _res
+ end.
+
+encode_mam_jid_cdata(_val, _acc) ->
+ [{xmlcdata, enc_jid(_val)} | _acc].
+
+decode_mam_result(__TopXMLNS, __IgnoreEls,
+ {xmlel, <<"result">>, _attrs, _els}) ->
+ __Els = decode_mam_result_els(__TopXMLNS, __IgnoreEls,
+ _els, []),
+ {Queryid, Xmlns, Id} =
+ decode_mam_result_attrs(__TopXMLNS, _attrs, undefined,
+ undefined, undefined),
+ {mam_result, Xmlns, Queryid, Id, __Els}.
+
+decode_mam_result_els(__TopXMLNS, __IgnoreEls, [],
+ __Els) ->
+ lists:reverse(__Els);
+decode_mam_result_els(__TopXMLNS, __IgnoreEls,
+ [{xmlel, _, _, _} = _el | _els], __Els) ->
+ if __IgnoreEls ->
+ decode_mam_result_els(__TopXMLNS, __IgnoreEls, _els,
+ [_el | __Els]);
+ true ->
+ case is_known_tag(_el) of
+ true ->
+ decode_mam_result_els(__TopXMLNS, __IgnoreEls, _els,
+ [decode(_el) | __Els]);
+ false ->
+ decode_mam_result_els(__TopXMLNS, __IgnoreEls, _els,
+ __Els)
+ end
+ end;
+decode_mam_result_els(__TopXMLNS, __IgnoreEls,
+ [_ | _els], __Els) ->
+ decode_mam_result_els(__TopXMLNS, __IgnoreEls, _els,
+ __Els).
+
+decode_mam_result_attrs(__TopXMLNS,
+ [{<<"queryid">>, _val} | _attrs], _Queryid, Xmlns,
+ Id) ->
+ decode_mam_result_attrs(__TopXMLNS, _attrs, _val, Xmlns,
+ Id);
+decode_mam_result_attrs(__TopXMLNS,
+ [{<<"xmlns">>, _val} | _attrs], Queryid, _Xmlns, Id) ->
+ decode_mam_result_attrs(__TopXMLNS, _attrs, Queryid,
+ _val, Id);
+decode_mam_result_attrs(__TopXMLNS,
+ [{<<"id">>, _val} | _attrs], Queryid, Xmlns, _Id) ->
+ decode_mam_result_attrs(__TopXMLNS, _attrs, Queryid,
+ Xmlns, _val);
+decode_mam_result_attrs(__TopXMLNS, [_ | _attrs],
+ Queryid, Xmlns, Id) ->
+ decode_mam_result_attrs(__TopXMLNS, _attrs, Queryid,
+ Xmlns, Id);
+decode_mam_result_attrs(__TopXMLNS, [], Queryid, Xmlns,
+ Id) ->
+ {decode_mam_result_attr_queryid(__TopXMLNS, Queryid),
+ decode_mam_result_attr_xmlns(__TopXMLNS, Xmlns),
+ decode_mam_result_attr_id(__TopXMLNS, Id)}.
+
+encode_mam_result({mam_result, Xmlns, Queryid, Id,
+ __Els},
+ _xmlns_attrs) ->
+ _els = [encode(_el) || _el <- __Els],
+ _attrs = encode_mam_result_attr_id(Id,
+ encode_mam_result_attr_xmlns(Xmlns,
+ encode_mam_result_attr_queryid(Queryid,
+ _xmlns_attrs))),
+ {xmlel, <<"result">>, _attrs, _els}.
+
+decode_mam_result_attr_queryid(__TopXMLNS, undefined) ->
+ undefined;
+decode_mam_result_attr_queryid(__TopXMLNS, _val) ->
+ _val.
+
+encode_mam_result_attr_queryid(undefined, _acc) -> _acc;
+encode_mam_result_attr_queryid(_val, _acc) ->
+ [{<<"queryid">>, _val} | _acc].
+
+decode_mam_result_attr_xmlns(__TopXMLNS, undefined) ->
+ undefined;
+decode_mam_result_attr_xmlns(__TopXMLNS, _val) -> _val.
+
+encode_mam_result_attr_xmlns(undefined, _acc) -> _acc;
+encode_mam_result_attr_xmlns(_val, _acc) ->
+ [{<<"xmlns">>, _val} | _acc].
+
+decode_mam_result_attr_id(__TopXMLNS, undefined) ->
+ undefined;
+decode_mam_result_attr_id(__TopXMLNS, _val) -> _val.
+
+encode_mam_result_attr_id(undefined, _acc) -> _acc;
+encode_mam_result_attr_id(_val, _acc) ->
+ [{<<"id">>, _val} | _acc].
+
+decode_mam_archived(__TopXMLNS, __IgnoreEls,
+ {xmlel, <<"archived">>, _attrs, _els}) ->
+ {Id, By} = decode_mam_archived_attrs(__TopXMLNS, _attrs,
+ undefined, undefined),
+ {mam_archived, By, Id}.
+
+decode_mam_archived_attrs(__TopXMLNS,
+ [{<<"id">>, _val} | _attrs], _Id, By) ->
+ decode_mam_archived_attrs(__TopXMLNS, _attrs, _val, By);
+decode_mam_archived_attrs(__TopXMLNS,
+ [{<<"by">>, _val} | _attrs], Id, _By) ->
+ decode_mam_archived_attrs(__TopXMLNS, _attrs, Id, _val);
+decode_mam_archived_attrs(__TopXMLNS, [_ | _attrs], Id,
+ By) ->
+ decode_mam_archived_attrs(__TopXMLNS, _attrs, Id, By);
+decode_mam_archived_attrs(__TopXMLNS, [], Id, By) ->
+ {decode_mam_archived_attr_id(__TopXMLNS, Id),
+ decode_mam_archived_attr_by(__TopXMLNS, By)}.
+
+encode_mam_archived({mam_archived, By, Id},
+ _xmlns_attrs) ->
+ _els = [],
+ _attrs = encode_mam_archived_attr_by(By,
+ encode_mam_archived_attr_id(Id,
+ _xmlns_attrs)),
+ {xmlel, <<"archived">>, _attrs, _els}.
+
+decode_mam_archived_attr_id(__TopXMLNS, undefined) ->
+ undefined;
+decode_mam_archived_attr_id(__TopXMLNS, _val) -> _val.
+
+encode_mam_archived_attr_id(undefined, _acc) -> _acc;
+encode_mam_archived_attr_id(_val, _acc) ->
+ [{<<"id">>, _val} | _acc].
+
+decode_mam_archived_attr_by(__TopXMLNS, undefined) ->
+ erlang:error({xmpp_codec,
+ {missing_attr, <<"by">>, <<"archived">>, __TopXMLNS}});
+decode_mam_archived_attr_by(__TopXMLNS, _val) ->
+ case catch dec_jid(_val) of
+ {'EXIT', _} ->
+ erlang:error({xmpp_codec,
+ {bad_attr_value, <<"by">>, <<"archived">>,
+ __TopXMLNS}});
+ _res -> _res
+ end.
+
+encode_mam_archived_attr_by(_val, _acc) ->
+ [{<<"by">>, enc_jid(_val)} | _acc].
+
+decode_mam_query(__TopXMLNS, __IgnoreEls,
+ {xmlel, <<"query">>, _attrs, _els}) ->
+ {Xdata, End, Start, With, Rsm} =
+ decode_mam_query_els(__TopXMLNS, __IgnoreEls, _els,
+ undefined, undefined, undefined, undefined,
+ undefined),
+ {Id, Xmlns} = decode_mam_query_attrs(__TopXMLNS, _attrs,
+ undefined, undefined),
+ {mam_query, Xmlns, Id, Start, End, With, Rsm, Xdata}.
+
+decode_mam_query_els(__TopXMLNS, __IgnoreEls, [], Xdata,
+ End, Start, With, Rsm) ->
+ {Xdata, End, Start, With, Rsm};
+decode_mam_query_els(__TopXMLNS, __IgnoreEls,
+ [{xmlel, <<"start">>, _attrs, _} = _el | _els], Xdata,
+ End, Start, With, Rsm) ->
+ _xmlns = get_attr(<<"xmlns">>, _attrs),
+ if _xmlns == <<>>; _xmlns == __TopXMLNS ->
+ decode_mam_query_els(__TopXMLNS, __IgnoreEls, _els,
+ Xdata, End,
+ decode_mam_start(__TopXMLNS, __IgnoreEls, _el),
+ With, Rsm);
+ true ->
+ decode_mam_query_els(__TopXMLNS, __IgnoreEls, _els,
+ Xdata, End, Start, With, Rsm)
+ end;
+decode_mam_query_els(__TopXMLNS, __IgnoreEls,
+ [{xmlel, <<"end">>, _attrs, _} = _el | _els], Xdata,
+ End, Start, With, Rsm) ->
+ _xmlns = get_attr(<<"xmlns">>, _attrs),
+ if _xmlns == <<>>; _xmlns == __TopXMLNS ->
+ decode_mam_query_els(__TopXMLNS, __IgnoreEls, _els,
+ Xdata,
+ decode_mam_end(__TopXMLNS, __IgnoreEls, _el),
+ Start, With, Rsm);
+ true ->
+ decode_mam_query_els(__TopXMLNS, __IgnoreEls, _els,
+ Xdata, End, Start, With, Rsm)
+ end;
+decode_mam_query_els(__TopXMLNS, __IgnoreEls,
+ [{xmlel, <<"with">>, _attrs, _} = _el | _els], Xdata,
+ End, Start, With, Rsm) ->
+ _xmlns = get_attr(<<"xmlns">>, _attrs),
+ if _xmlns == <<>>; _xmlns == __TopXMLNS ->
+ decode_mam_query_els(__TopXMLNS, __IgnoreEls, _els,
+ Xdata, End, Start,
+ decode_mam_with(__TopXMLNS, __IgnoreEls, _el),
+ Rsm);
+ true ->
+ decode_mam_query_els(__TopXMLNS, __IgnoreEls, _els,
+ Xdata, End, Start, With, Rsm)
+ end;
+decode_mam_query_els(__TopXMLNS, __IgnoreEls,
+ [{xmlel, <<"set">>, _attrs, _} = _el | _els], Xdata,
+ End, Start, With, Rsm) ->
+ _xmlns = get_attr(<<"xmlns">>, _attrs),
+ if _xmlns == <<"http://jabber.org/protocol/rsm">> ->
+ decode_mam_query_els(__TopXMLNS, __IgnoreEls, _els,
+ Xdata, End, Start, With,
+ decode_rsm_set(_xmlns, __IgnoreEls, _el));
+ true ->
+ decode_mam_query_els(__TopXMLNS, __IgnoreEls, _els,
+ Xdata, End, Start, With, Rsm)
+ end;
+decode_mam_query_els(__TopXMLNS, __IgnoreEls,
+ [{xmlel, <<"x">>, _attrs, _} = _el | _els], Xdata, End,
+ Start, With, Rsm) ->
+ _xmlns = get_attr(<<"xmlns">>, _attrs),
+ if _xmlns == <<"jabber:x:data">> ->
+ decode_mam_query_els(__TopXMLNS, __IgnoreEls, _els,
+ decode_xdata(_xmlns, __IgnoreEls, _el), End,
+ Start, With, Rsm);
+ true ->
+ decode_mam_query_els(__TopXMLNS, __IgnoreEls, _els,
+ Xdata, End, Start, With, Rsm)
+ end;
+decode_mam_query_els(__TopXMLNS, __IgnoreEls,
+ [_ | _els], Xdata, End, Start, With, Rsm) ->
+ decode_mam_query_els(__TopXMLNS, __IgnoreEls, _els,
+ Xdata, End, Start, With, Rsm).
+
+decode_mam_query_attrs(__TopXMLNS,
+ [{<<"queryid">>, _val} | _attrs], _Id, Xmlns) ->
+ decode_mam_query_attrs(__TopXMLNS, _attrs, _val, Xmlns);
+decode_mam_query_attrs(__TopXMLNS,
+ [{<<"xmlns">>, _val} | _attrs], Id, _Xmlns) ->
+ decode_mam_query_attrs(__TopXMLNS, _attrs, Id, _val);
+decode_mam_query_attrs(__TopXMLNS, [_ | _attrs], Id,
+ Xmlns) ->
+ decode_mam_query_attrs(__TopXMLNS, _attrs, Id, Xmlns);
+decode_mam_query_attrs(__TopXMLNS, [], Id, Xmlns) ->
+ {decode_mam_query_attr_queryid(__TopXMLNS, Id),
+ decode_mam_query_attr_xmlns(__TopXMLNS, Xmlns)}.
+
+encode_mam_query({mam_query, Xmlns, Id, Start, End,
+ With, Rsm, Xdata},
+ _xmlns_attrs) ->
+ _els = lists:reverse('encode_mam_query_$xdata'(Xdata,
+ 'encode_mam_query_$end'(End,
+ 'encode_mam_query_$start'(Start,
+ 'encode_mam_query_$with'(With,
+ 'encode_mam_query_$rsm'(Rsm,
+ [])))))),
+ _attrs = encode_mam_query_attr_xmlns(Xmlns,
+ encode_mam_query_attr_queryid(Id,
+ _xmlns_attrs)),
+ {xmlel, <<"query">>, _attrs, _els}.
+
+'encode_mam_query_$xdata'(undefined, _acc) -> _acc;
+'encode_mam_query_$xdata'(Xdata, _acc) ->
+ [encode_xdata(Xdata,
+ [{<<"xmlns">>, <<"jabber:x:data">>}])
+ | _acc].
+
+'encode_mam_query_$end'(undefined, _acc) -> _acc;
+'encode_mam_query_$end'(End, _acc) ->
+ [encode_mam_end(End,
+ [{<<"xmlns">>, <<"urn:xmpp:mam:tmp">>}])
+ | _acc].
+
+'encode_mam_query_$start'(undefined, _acc) -> _acc;
+'encode_mam_query_$start'(Start, _acc) ->
+ [encode_mam_start(Start,
+ [{<<"xmlns">>, <<"urn:xmpp:mam:tmp">>}])
+ | _acc].
+
+'encode_mam_query_$with'(undefined, _acc) -> _acc;
+'encode_mam_query_$with'(With, _acc) ->
+ [encode_mam_with(With,
+ [{<<"xmlns">>, <<"urn:xmpp:mam:tmp">>}])
+ | _acc].
+
+'encode_mam_query_$rsm'(undefined, _acc) -> _acc;
+'encode_mam_query_$rsm'(Rsm, _acc) ->
+ [encode_rsm_set(Rsm,
+ [{<<"xmlns">>, <<"http://jabber.org/protocol/rsm">>}])
+ | _acc].
+
+decode_mam_query_attr_queryid(__TopXMLNS, undefined) ->
+ undefined;
+decode_mam_query_attr_queryid(__TopXMLNS, _val) -> _val.
+
+encode_mam_query_attr_queryid(undefined, _acc) -> _acc;
+encode_mam_query_attr_queryid(_val, _acc) ->
+ [{<<"queryid">>, _val} | _acc].
+
+decode_mam_query_attr_xmlns(__TopXMLNS, undefined) ->
+ undefined;
+decode_mam_query_attr_xmlns(__TopXMLNS, _val) -> _val.
+
+encode_mam_query_attr_xmlns(undefined, _acc) -> _acc;
+encode_mam_query_attr_xmlns(_val, _acc) ->
+ [{<<"xmlns">>, _val} | _acc].
+
+decode_mam_with(__TopXMLNS, __IgnoreEls,
+ {xmlel, <<"with">>, _attrs, _els}) ->
+ Cdata = decode_mam_with_els(__TopXMLNS, __IgnoreEls,
+ _els, <<>>),
+ Cdata.
+
+decode_mam_with_els(__TopXMLNS, __IgnoreEls, [],
+ Cdata) ->
+ decode_mam_with_cdata(__TopXMLNS, Cdata);
+decode_mam_with_els(__TopXMLNS, __IgnoreEls,
+ [{xmlcdata, _data} | _els], Cdata) ->
+ decode_mam_with_els(__TopXMLNS, __IgnoreEls, _els,
+ <<Cdata/binary, _data/binary>>);
+decode_mam_with_els(__TopXMLNS, __IgnoreEls, [_ | _els],
+ Cdata) ->
+ decode_mam_with_els(__TopXMLNS, __IgnoreEls, _els,
+ Cdata).
+
+encode_mam_with(Cdata, _xmlns_attrs) ->
+ _els = encode_mam_with_cdata(Cdata, []),
+ _attrs = _xmlns_attrs,
+ {xmlel, <<"with">>, _attrs, _els}.
+
+decode_mam_with_cdata(__TopXMLNS, <<>>) ->
+ erlang:error({xmpp_codec,
+ {missing_cdata, <<>>, <<"with">>, __TopXMLNS}});
+decode_mam_with_cdata(__TopXMLNS, _val) ->
+ case catch dec_jid(_val) of
+ {'EXIT', _} ->
+ erlang:error({xmpp_codec,
+ {bad_cdata_value, <<>>, <<"with">>, __TopXMLNS}});
+ _res -> _res
+ end.
+
+encode_mam_with_cdata(_val, _acc) ->
+ [{xmlcdata, enc_jid(_val)} | _acc].
+
+decode_mam_end(__TopXMLNS, __IgnoreEls,
+ {xmlel, <<"end">>, _attrs, _els}) ->
+ Cdata = decode_mam_end_els(__TopXMLNS, __IgnoreEls,
+ _els, <<>>),
+ Cdata.
+
+decode_mam_end_els(__TopXMLNS, __IgnoreEls, [],
+ Cdata) ->
+ decode_mam_end_cdata(__TopXMLNS, Cdata);
+decode_mam_end_els(__TopXMLNS, __IgnoreEls,
+ [{xmlcdata, _data} | _els], Cdata) ->
+ decode_mam_end_els(__TopXMLNS, __IgnoreEls, _els,
+ <<Cdata/binary, _data/binary>>);
+decode_mam_end_els(__TopXMLNS, __IgnoreEls, [_ | _els],
+ Cdata) ->
+ decode_mam_end_els(__TopXMLNS, __IgnoreEls, _els,
+ Cdata).
+
+encode_mam_end(Cdata, _xmlns_attrs) ->
+ _els = encode_mam_end_cdata(Cdata, []),
+ _attrs = _xmlns_attrs,
+ {xmlel, <<"end">>, _attrs, _els}.
+
+decode_mam_end_cdata(__TopXMLNS, <<>>) ->
+ erlang:error({xmpp_codec,
+ {missing_cdata, <<>>, <<"end">>, __TopXMLNS}});
+decode_mam_end_cdata(__TopXMLNS, _val) ->
+ case catch dec_utc(_val) of
+ {'EXIT', _} ->
+ erlang:error({xmpp_codec,
+ {bad_cdata_value, <<>>, <<"end">>, __TopXMLNS}});
+ _res -> _res
+ end.
+
+encode_mam_end_cdata(_val, _acc) ->
+ [{xmlcdata, enc_utc(_val)} | _acc].
+
+decode_mam_start(__TopXMLNS, __IgnoreEls,
+ {xmlel, <<"start">>, _attrs, _els}) ->
+ Cdata = decode_mam_start_els(__TopXMLNS, __IgnoreEls,
+ _els, <<>>),
+ Cdata.
+
+decode_mam_start_els(__TopXMLNS, __IgnoreEls, [],
+ Cdata) ->
+ decode_mam_start_cdata(__TopXMLNS, Cdata);
+decode_mam_start_els(__TopXMLNS, __IgnoreEls,
+ [{xmlcdata, _data} | _els], Cdata) ->
+ decode_mam_start_els(__TopXMLNS, __IgnoreEls, _els,
+ <<Cdata/binary, _data/binary>>);
+decode_mam_start_els(__TopXMLNS, __IgnoreEls,
+ [_ | _els], Cdata) ->
+ decode_mam_start_els(__TopXMLNS, __IgnoreEls, _els,
+ Cdata).
+
+encode_mam_start(Cdata, _xmlns_attrs) ->
+ _els = encode_mam_start_cdata(Cdata, []),
+ _attrs = _xmlns_attrs,
+ {xmlel, <<"start">>, _attrs, _els}.
+
+decode_mam_start_cdata(__TopXMLNS, <<>>) ->
+ erlang:error({xmpp_codec,
+ {missing_cdata, <<>>, <<"start">>, __TopXMLNS}});
+decode_mam_start_cdata(__TopXMLNS, _val) ->
+ case catch dec_utc(_val) of
+ {'EXIT', _} ->
+ erlang:error({xmpp_codec,
+ {bad_cdata_value, <<>>, <<"start">>, __TopXMLNS}});
+ _res -> _res
+ end.
+
+encode_mam_start_cdata(_val, _acc) ->
+ [{xmlcdata, enc_utc(_val)} | _acc].
+
+decode_rsm_set(__TopXMLNS, __IgnoreEls,
+ {xmlel, <<"set">>, _attrs, _els}) ->
+ {After, Last, First, Count, Before, Max, Index} =
+ decode_rsm_set_els(__TopXMLNS, __IgnoreEls, _els,
+ undefined, undefined, undefined, undefined,
+ undefined, undefined, undefined),
+ {rsm_set, After, Before, Count, First, Index, Last,
+ Max}.
+
+decode_rsm_set_els(__TopXMLNS, __IgnoreEls, [], After,
+ Last, First, Count, Before, Max, Index) ->
+ {After, Last, First, Count, Before, Max, Index};
+decode_rsm_set_els(__TopXMLNS, __IgnoreEls,
+ [{xmlel, <<"after">>, _attrs, _} = _el | _els], After,
+ Last, First, Count, Before, Max, Index) ->
+ _xmlns = get_attr(<<"xmlns">>, _attrs),
+ if _xmlns == <<>>; _xmlns == __TopXMLNS ->
+ decode_rsm_set_els(__TopXMLNS, __IgnoreEls, _els,
+ decode_rsm_after(__TopXMLNS, __IgnoreEls, _el),
+ Last, First, Count, Before, Max, Index);
+ true ->
+ decode_rsm_set_els(__TopXMLNS, __IgnoreEls, _els, After,
+ Last, First, Count, Before, Max, Index)
+ end;
+decode_rsm_set_els(__TopXMLNS, __IgnoreEls,
+ [{xmlel, <<"before">>, _attrs, _} = _el | _els], After,
+ Last, First, Count, Before, Max, Index) ->
+ _xmlns = get_attr(<<"xmlns">>, _attrs),
+ if _xmlns == <<>>; _xmlns == __TopXMLNS ->
+ decode_rsm_set_els(__TopXMLNS, __IgnoreEls, _els, After,
+ Last, First, Count,
+ decode_rsm_before(__TopXMLNS, __IgnoreEls, _el),
+ Max, Index);
+ true ->
+ decode_rsm_set_els(__TopXMLNS, __IgnoreEls, _els, After,
+ Last, First, Count, Before, Max, Index)
+ end;
+decode_rsm_set_els(__TopXMLNS, __IgnoreEls,
+ [{xmlel, <<"count">>, _attrs, _} = _el | _els], After,
+ Last, First, Count, Before, Max, Index) ->
+ _xmlns = get_attr(<<"xmlns">>, _attrs),
+ if _xmlns == <<>>; _xmlns == __TopXMLNS ->
+ decode_rsm_set_els(__TopXMLNS, __IgnoreEls, _els, After,
+ Last, First,
+ decode_rsm_count(__TopXMLNS, __IgnoreEls, _el),
+ Before, Max, Index);
+ true ->
+ decode_rsm_set_els(__TopXMLNS, __IgnoreEls, _els, After,
+ Last, First, Count, Before, Max, Index)
+ end;
+decode_rsm_set_els(__TopXMLNS, __IgnoreEls,
+ [{xmlel, <<"first">>, _attrs, _} = _el | _els], After,
+ Last, First, Count, Before, Max, Index) ->
+ _xmlns = get_attr(<<"xmlns">>, _attrs),
+ if _xmlns == <<>>; _xmlns == __TopXMLNS ->
+ decode_rsm_set_els(__TopXMLNS, __IgnoreEls, _els, After,
+ Last,
+ decode_rsm_first(__TopXMLNS, __IgnoreEls, _el),
+ Count, Before, Max, Index);
+ true ->
+ decode_rsm_set_els(__TopXMLNS, __IgnoreEls, _els, After,
+ Last, First, Count, Before, Max, Index)
+ end;
+decode_rsm_set_els(__TopXMLNS, __IgnoreEls,
+ [{xmlel, <<"index">>, _attrs, _} = _el | _els], After,
+ Last, First, Count, Before, Max, Index) ->
+ _xmlns = get_attr(<<"xmlns">>, _attrs),
+ if _xmlns == <<>>; _xmlns == __TopXMLNS ->
+ decode_rsm_set_els(__TopXMLNS, __IgnoreEls, _els, After,
+ Last, First, Count, Before, Max,
+ decode_rsm_index(__TopXMLNS, __IgnoreEls, _el));
+ true ->
+ decode_rsm_set_els(__TopXMLNS, __IgnoreEls, _els, After,
+ Last, First, Count, Before, Max, Index)
+ end;
+decode_rsm_set_els(__TopXMLNS, __IgnoreEls,
+ [{xmlel, <<"last">>, _attrs, _} = _el | _els], After,
+ Last, First, Count, Before, Max, Index) ->
+ _xmlns = get_attr(<<"xmlns">>, _attrs),
+ if _xmlns == <<>>; _xmlns == __TopXMLNS ->
+ decode_rsm_set_els(__TopXMLNS, __IgnoreEls, _els, After,
+ decode_rsm_last(__TopXMLNS, __IgnoreEls, _el),
+ First, Count, Before, Max, Index);
+ true ->
+ decode_rsm_set_els(__TopXMLNS, __IgnoreEls, _els, After,
+ Last, First, Count, Before, Max, Index)
+ end;
+decode_rsm_set_els(__TopXMLNS, __IgnoreEls,
+ [{xmlel, <<"max">>, _attrs, _} = _el | _els], After,
+ Last, First, Count, Before, Max, Index) ->
+ _xmlns = get_attr(<<"xmlns">>, _attrs),
+ if _xmlns == <<>>; _xmlns == __TopXMLNS ->
+ decode_rsm_set_els(__TopXMLNS, __IgnoreEls, _els, After,
+ Last, First, Count, Before,
+ decode_rsm_max(__TopXMLNS, __IgnoreEls, _el),
+ Index);
+ true ->
+ decode_rsm_set_els(__TopXMLNS, __IgnoreEls, _els, After,
+ Last, First, Count, Before, Max, Index)
+ end;
+decode_rsm_set_els(__TopXMLNS, __IgnoreEls, [_ | _els],
+ After, Last, First, Count, Before, Max, Index) ->
+ decode_rsm_set_els(__TopXMLNS, __IgnoreEls, _els, After,
+ Last, First, Count, Before, Max, Index).
+
+encode_rsm_set({rsm_set, After, Before, Count, First,
+ Index, Last, Max},
+ _xmlns_attrs) ->
+ _els = lists:reverse('encode_rsm_set_$after'(After,
+ 'encode_rsm_set_$last'(Last,
+ 'encode_rsm_set_$first'(First,
+ 'encode_rsm_set_$count'(Count,
+ 'encode_rsm_set_$before'(Before,
+ 'encode_rsm_set_$max'(Max,
+ 'encode_rsm_set_$index'(Index,
+ [])))))))),
+ _attrs = _xmlns_attrs,
+ {xmlel, <<"set">>, _attrs, _els}.
+
+'encode_rsm_set_$after'(undefined, _acc) -> _acc;
+'encode_rsm_set_$after'(After, _acc) ->
+ [encode_rsm_after(After, []) | _acc].
+
+'encode_rsm_set_$last'(undefined, _acc) -> _acc;
+'encode_rsm_set_$last'(Last, _acc) ->
+ [encode_rsm_last(Last, []) | _acc].
+
+'encode_rsm_set_$first'(undefined, _acc) -> _acc;
+'encode_rsm_set_$first'(First, _acc) ->
+ [encode_rsm_first(First, []) | _acc].
+
+'encode_rsm_set_$count'(undefined, _acc) -> _acc;
+'encode_rsm_set_$count'(Count, _acc) ->
+ [encode_rsm_count(Count, []) | _acc].
+
+'encode_rsm_set_$before'(undefined, _acc) -> _acc;
+'encode_rsm_set_$before'(Before, _acc) ->
+ [encode_rsm_before(Before, []) | _acc].
+
+'encode_rsm_set_$max'(undefined, _acc) -> _acc;
+'encode_rsm_set_$max'(Max, _acc) ->
+ [encode_rsm_max(Max, []) | _acc].
+
+'encode_rsm_set_$index'(undefined, _acc) -> _acc;
+'encode_rsm_set_$index'(Index, _acc) ->
+ [encode_rsm_index(Index, []) | _acc].
+
+decode_rsm_first(__TopXMLNS, __IgnoreEls,
+ {xmlel, <<"first">>, _attrs, _els}) ->
+ Data = decode_rsm_first_els(__TopXMLNS, __IgnoreEls,
+ _els, <<>>),
+ Index = decode_rsm_first_attrs(__TopXMLNS, _attrs,
+ undefined),
+ {rsm_first, Index, Data}.
+
+decode_rsm_first_els(__TopXMLNS, __IgnoreEls, [],
+ Data) ->
+ decode_rsm_first_cdata(__TopXMLNS, Data);
+decode_rsm_first_els(__TopXMLNS, __IgnoreEls,
+ [{xmlcdata, _data} | _els], Data) ->
+ decode_rsm_first_els(__TopXMLNS, __IgnoreEls, _els,
+ <<Data/binary, _data/binary>>);
+decode_rsm_first_els(__TopXMLNS, __IgnoreEls,
+ [_ | _els], Data) ->
+ decode_rsm_first_els(__TopXMLNS, __IgnoreEls, _els,
+ Data).
+
+decode_rsm_first_attrs(__TopXMLNS,
+ [{<<"index">>, _val} | _attrs], _Index) ->
+ decode_rsm_first_attrs(__TopXMLNS, _attrs, _val);
+decode_rsm_first_attrs(__TopXMLNS, [_ | _attrs],
+ Index) ->
+ decode_rsm_first_attrs(__TopXMLNS, _attrs, Index);
+decode_rsm_first_attrs(__TopXMLNS, [], Index) ->
+ decode_rsm_first_attr_index(__TopXMLNS, Index).
+
+encode_rsm_first({rsm_first, Index, Data},
+ _xmlns_attrs) ->
+ _els = encode_rsm_first_cdata(Data, []),
+ _attrs = encode_rsm_first_attr_index(Index,
+ _xmlns_attrs),
+ {xmlel, <<"first">>, _attrs, _els}.
+
+decode_rsm_first_attr_index(__TopXMLNS, undefined) ->
+ undefined;
+decode_rsm_first_attr_index(__TopXMLNS, _val) ->
+ case catch dec_int(_val, 0, infinity) of
+ {'EXIT', _} ->
+ erlang:error({xmpp_codec,
+ {bad_attr_value, <<"index">>, <<"first">>,
+ __TopXMLNS}});
+ _res -> _res
+ end.
+
+encode_rsm_first_attr_index(undefined, _acc) -> _acc;
+encode_rsm_first_attr_index(_val, _acc) ->
+ [{<<"index">>, enc_int(_val)} | _acc].
+
+decode_rsm_first_cdata(__TopXMLNS, <<>>) -> undefined;
+decode_rsm_first_cdata(__TopXMLNS, _val) -> _val.
+
+encode_rsm_first_cdata(undefined, _acc) -> _acc;
+encode_rsm_first_cdata(_val, _acc) ->
+ [{xmlcdata, _val} | _acc].
+
+decode_rsm_max(__TopXMLNS, __IgnoreEls,
+ {xmlel, <<"max">>, _attrs, _els}) ->
+ Cdata = decode_rsm_max_els(__TopXMLNS, __IgnoreEls,
+ _els, <<>>),
+ Cdata.
+
+decode_rsm_max_els(__TopXMLNS, __IgnoreEls, [],
+ Cdata) ->
+ decode_rsm_max_cdata(__TopXMLNS, Cdata);
+decode_rsm_max_els(__TopXMLNS, __IgnoreEls,
+ [{xmlcdata, _data} | _els], Cdata) ->
+ decode_rsm_max_els(__TopXMLNS, __IgnoreEls, _els,
+ <<Cdata/binary, _data/binary>>);
+decode_rsm_max_els(__TopXMLNS, __IgnoreEls, [_ | _els],
+ Cdata) ->
+ decode_rsm_max_els(__TopXMLNS, __IgnoreEls, _els,
+ Cdata).
+
+encode_rsm_max(Cdata, _xmlns_attrs) ->
+ _els = encode_rsm_max_cdata(Cdata, []),
+ _attrs = _xmlns_attrs,
+ {xmlel, <<"max">>, _attrs, _els}.
+
+decode_rsm_max_cdata(__TopXMLNS, <<>>) -> undefined;
+decode_rsm_max_cdata(__TopXMLNS, _val) ->
+ case catch dec_int(_val, 0, infinity) of
+ {'EXIT', _} ->
+ erlang:error({xmpp_codec,
+ {bad_cdata_value, <<>>, <<"max">>, __TopXMLNS}});
+ _res -> _res
+ end.
+
+encode_rsm_max_cdata(undefined, _acc) -> _acc;
+encode_rsm_max_cdata(_val, _acc) ->
+ [{xmlcdata, enc_int(_val)} | _acc].
+
+decode_rsm_index(__TopXMLNS, __IgnoreEls,
+ {xmlel, <<"index">>, _attrs, _els}) ->
+ Cdata = decode_rsm_index_els(__TopXMLNS, __IgnoreEls,
+ _els, <<>>),
+ Cdata.
+
+decode_rsm_index_els(__TopXMLNS, __IgnoreEls, [],
+ Cdata) ->
+ decode_rsm_index_cdata(__TopXMLNS, Cdata);
+decode_rsm_index_els(__TopXMLNS, __IgnoreEls,
+ [{xmlcdata, _data} | _els], Cdata) ->
+ decode_rsm_index_els(__TopXMLNS, __IgnoreEls, _els,
+ <<Cdata/binary, _data/binary>>);
+decode_rsm_index_els(__TopXMLNS, __IgnoreEls,
+ [_ | _els], Cdata) ->
+ decode_rsm_index_els(__TopXMLNS, __IgnoreEls, _els,
+ Cdata).
+
+encode_rsm_index(Cdata, _xmlns_attrs) ->
+ _els = encode_rsm_index_cdata(Cdata, []),
+ _attrs = _xmlns_attrs,
+ {xmlel, <<"index">>, _attrs, _els}.
+
+decode_rsm_index_cdata(__TopXMLNS, <<>>) -> undefined;
+decode_rsm_index_cdata(__TopXMLNS, _val) ->
+ case catch dec_int(_val, 0, infinity) of
+ {'EXIT', _} ->
+ erlang:error({xmpp_codec,
+ {bad_cdata_value, <<>>, <<"index">>, __TopXMLNS}});
+ _res -> _res
+ end.
+
+encode_rsm_index_cdata(undefined, _acc) -> _acc;
+encode_rsm_index_cdata(_val, _acc) ->
+ [{xmlcdata, enc_int(_val)} | _acc].
+
+decode_rsm_count(__TopXMLNS, __IgnoreEls,
+ {xmlel, <<"count">>, _attrs, _els}) ->
+ Cdata = decode_rsm_count_els(__TopXMLNS, __IgnoreEls,
+ _els, <<>>),
+ Cdata.
+
+decode_rsm_count_els(__TopXMLNS, __IgnoreEls, [],
+ Cdata) ->
+ decode_rsm_count_cdata(__TopXMLNS, Cdata);
+decode_rsm_count_els(__TopXMLNS, __IgnoreEls,
+ [{xmlcdata, _data} | _els], Cdata) ->
+ decode_rsm_count_els(__TopXMLNS, __IgnoreEls, _els,
+ <<Cdata/binary, _data/binary>>);
+decode_rsm_count_els(__TopXMLNS, __IgnoreEls,
+ [_ | _els], Cdata) ->
+ decode_rsm_count_els(__TopXMLNS, __IgnoreEls, _els,
+ Cdata).
+
+encode_rsm_count(Cdata, _xmlns_attrs) ->
+ _els = encode_rsm_count_cdata(Cdata, []),
+ _attrs = _xmlns_attrs,
+ {xmlel, <<"count">>, _attrs, _els}.
+
+decode_rsm_count_cdata(__TopXMLNS, <<>>) -> undefined;
+decode_rsm_count_cdata(__TopXMLNS, _val) ->
+ case catch dec_int(_val, 0, infinity) of
+ {'EXIT', _} ->
+ erlang:error({xmpp_codec,
+ {bad_cdata_value, <<>>, <<"count">>, __TopXMLNS}});
+ _res -> _res
+ end.
+
+encode_rsm_count_cdata(undefined, _acc) -> _acc;
+encode_rsm_count_cdata(_val, _acc) ->
+ [{xmlcdata, enc_int(_val)} | _acc].
+
+decode_rsm_last(__TopXMLNS, __IgnoreEls,
+ {xmlel, <<"last">>, _attrs, _els}) ->
+ Cdata = decode_rsm_last_els(__TopXMLNS, __IgnoreEls,
+ _els, <<>>),
+ Cdata.
+
+decode_rsm_last_els(__TopXMLNS, __IgnoreEls, [],
+ Cdata) ->
+ decode_rsm_last_cdata(__TopXMLNS, Cdata);
+decode_rsm_last_els(__TopXMLNS, __IgnoreEls,
+ [{xmlcdata, _data} | _els], Cdata) ->
+ decode_rsm_last_els(__TopXMLNS, __IgnoreEls, _els,
+ <<Cdata/binary, _data/binary>>);
+decode_rsm_last_els(__TopXMLNS, __IgnoreEls, [_ | _els],
+ Cdata) ->
+ decode_rsm_last_els(__TopXMLNS, __IgnoreEls, _els,
+ Cdata).
+
+encode_rsm_last(Cdata, _xmlns_attrs) ->
+ _els = encode_rsm_last_cdata(Cdata, []),
+ _attrs = _xmlns_attrs,
+ {xmlel, <<"last">>, _attrs, _els}.
+
+decode_rsm_last_cdata(__TopXMLNS, <<>>) -> undefined;
+decode_rsm_last_cdata(__TopXMLNS, _val) -> _val.
+
+encode_rsm_last_cdata(undefined, _acc) -> _acc;
+encode_rsm_last_cdata(_val, _acc) ->
+ [{xmlcdata, _val} | _acc].
+
+decode_rsm_before(__TopXMLNS, __IgnoreEls,
+ {xmlel, <<"before">>, _attrs, _els}) ->
+ Cdata = decode_rsm_before_els(__TopXMLNS, __IgnoreEls,
+ _els, <<>>),
+ Cdata.
+
+decode_rsm_before_els(__TopXMLNS, __IgnoreEls, [],
+ Cdata) ->
+ decode_rsm_before_cdata(__TopXMLNS, Cdata);
+decode_rsm_before_els(__TopXMLNS, __IgnoreEls,
+ [{xmlcdata, _data} | _els], Cdata) ->
+ decode_rsm_before_els(__TopXMLNS, __IgnoreEls, _els,
+ <<Cdata/binary, _data/binary>>);
+decode_rsm_before_els(__TopXMLNS, __IgnoreEls,
+ [_ | _els], Cdata) ->
+ decode_rsm_before_els(__TopXMLNS, __IgnoreEls, _els,
+ Cdata).
+
+encode_rsm_before(Cdata, _xmlns_attrs) ->
+ _els = encode_rsm_before_cdata(Cdata, []),
+ _attrs = _xmlns_attrs,
+ {xmlel, <<"before">>, _attrs, _els}.
+
+decode_rsm_before_cdata(__TopXMLNS, <<>>) -> undefined;
+decode_rsm_before_cdata(__TopXMLNS, _val) -> _val.
+
+encode_rsm_before_cdata(undefined, _acc) -> _acc;
+encode_rsm_before_cdata(_val, _acc) ->
+ [{xmlcdata, _val} | _acc].
+
+decode_rsm_after(__TopXMLNS, __IgnoreEls,
+ {xmlel, <<"after">>, _attrs, _els}) ->
+ Cdata = decode_rsm_after_els(__TopXMLNS, __IgnoreEls,
+ _els, <<>>),
+ Cdata.
+
+decode_rsm_after_els(__TopXMLNS, __IgnoreEls, [],
+ Cdata) ->
+ decode_rsm_after_cdata(__TopXMLNS, Cdata);
+decode_rsm_after_els(__TopXMLNS, __IgnoreEls,
+ [{xmlcdata, _data} | _els], Cdata) ->
+ decode_rsm_after_els(__TopXMLNS, __IgnoreEls, _els,
+ <<Cdata/binary, _data/binary>>);
+decode_rsm_after_els(__TopXMLNS, __IgnoreEls,
+ [_ | _els], Cdata) ->
+ decode_rsm_after_els(__TopXMLNS, __IgnoreEls, _els,
+ Cdata).
+
+encode_rsm_after(Cdata, _xmlns_attrs) ->
+ _els = encode_rsm_after_cdata(Cdata, []),
+ _attrs = _xmlns_attrs,
+ {xmlel, <<"after">>, _attrs, _els}.
+
+decode_rsm_after_cdata(__TopXMLNS, <<>>) -> undefined;
+decode_rsm_after_cdata(__TopXMLNS, _val) -> _val.
+
+encode_rsm_after_cdata(undefined, _acc) -> _acc;
+encode_rsm_after_cdata(_val, _acc) ->
+ [{xmlcdata, _val} | _acc].
+
decode_muc(__TopXMLNS, __IgnoreEls,
{xmlel, <<"x">>, _attrs, _els}) ->
History = decode_muc_els(__TopXMLNS, __IgnoreEls, _els,
diff --git a/tools/xmpp_codec.hrl b/tools/xmpp_codec.hrl
index af5903c93..567946fe2 100644
--- a/tools/xmpp_codec.hrl
+++ b/tools/xmpp_codec.hrl
@@ -9,6 +9,14 @@
-record(sasl_success, {text :: any()}).
+-record(mam_result, {xmlns :: binary(),
+ queryid :: binary(),
+ id :: binary(),
+ sub_els = [] :: [any()]}).
+
+-record(rsm_first, {index :: non_neg_integer(),
+ data :: binary()}).
+
-record(text, {lang :: binary(),
data :: binary()}).
@@ -176,6 +184,11 @@
-record(shim, {headers = [] :: [{binary(),'undefined' | binary()}]}).
+-record(mam_prefs, {xmlns :: binary(),
+ default :: 'always' | 'never' | 'roster',
+ always = [] :: [any()],
+ never = [] :: [any()]}).
+
-record(caps, {hash :: binary(),
node :: binary(),
ver :: any()}).
@@ -194,6 +207,9 @@
-record(carbons_sent, {forwarded :: #forwarded{}}).
+-record(mam_archived, {by :: any(),
+ id :: binary()}).
+
-record(p1_rebind, {}).
-record(compress_failure, {reason :: 'processing-failed' | 'setup-failed' | 'unsupported-method'}).
@@ -263,6 +279,17 @@
-record(vcard_org, {name :: binary(),
units = [] :: [binary()]}).
+-record(rsm_set, {'after' :: binary(),
+ before :: binary(),
+ count :: non_neg_integer(),
+ first :: #rsm_first{},
+ index :: non_neg_integer(),
+ last :: binary(),
+ max :: non_neg_integer()}).
+
+-record(mam_fin, {id :: binary(),
+ rsm :: #rsm_set{}}).
+
-record(vcard_tel, {home = false :: boolean(),
work = false :: boolean(),
voice = false :: boolean(),
@@ -343,6 +370,14 @@
items = [] :: [[#xdata_field{}]],
fields = [] :: [#xdata_field{}]}).
+-record(mam_query, {xmlns :: binary(),
+ id :: binary(),
+ start :: any(),
+ 'end' :: any(),
+ with :: any(),
+ rsm :: #rsm_set{},
+ xdata :: #xdata{}}).
+
-record(muc_owner, {destroy :: #muc_owner_destroy{},
config :: #xdata{}}).
diff --git a/tools/xmpp_codec.spec b/tools/xmpp_codec.spec
index e8cf0612b..dfa516ef5 100644
--- a/tools/xmpp_codec.spec
+++ b/tools/xmpp_codec.spec
@@ -2063,6 +2063,156 @@
refs = [#ref{name = muc_history, min = 0, max = 1,
label = '$history'}]}).
+-xml(rsm_after,
+ #elem{name = <<"after">>,
+ xmlns = <<"http://jabber.org/protocol/rsm">>,
+ result = '$cdata'}).
+
+-xml(rsm_before,
+ #elem{name = <<"before">>,
+ xmlns = <<"http://jabber.org/protocol/rsm">>,
+ result = '$cdata'}).
+
+-xml(rsm_last,
+ #elem{name = <<"last">>,
+ xmlns = <<"http://jabber.org/protocol/rsm">>,
+ result = '$cdata'}).
+
+-xml(rsm_count,
+ #elem{name = <<"count">>, result = '$cdata',
+ xmlns = <<"http://jabber.org/protocol/rsm">>,
+ cdata = #cdata{dec = {dec_int, [0, infinity]},
+ enc = {enc_int, []}}}).
+
+-xml(rsm_index,
+ #elem{name = <<"index">>, result = '$cdata',
+ xmlns = <<"http://jabber.org/protocol/rsm">>,
+ cdata = #cdata{dec = {dec_int, [0, infinity]},
+ enc = {enc_int, []}}}).
+
+-xml(rsm_max,
+ #elem{name = <<"max">>, result = '$cdata',
+ xmlns = <<"http://jabber.org/protocol/rsm">>,
+ cdata = #cdata{dec = {dec_int, [0, infinity]},
+ enc = {enc_int, []}}}).
+
+-xml(rsm_first,
+ #elem{name = <<"first">>,
+ xmlns = <<"http://jabber.org/protocol/rsm">>,
+ result = {rsm_first, '$index', '$data'},
+ cdata = #cdata{label = '$data'},
+ attrs = [#attr{name = <<"index">>,
+ dec = {dec_int, [0, infinity]},
+ enc = {enc_int, []}}]}).
+
+-xml(rsm_set,
+ #elem{name = <<"set">>,
+ xmlns = <<"http://jabber.org/protocol/rsm">>,
+ result = {rsm_set, '$after', '$before', '$count',
+ '$first', '$index', '$last', '$max'},
+ refs = [#ref{name = rsm_after, label = '$after', min = 0, max = 1},
+ #ref{name = rsm_before, label = '$before', min = 0, max = 1},
+ #ref{name = rsm_count, label = '$count', min = 0, max = 1},
+ #ref{name = rsm_first, label = '$first', min = 0, max = 1},
+ #ref{name = rsm_index, label = '$index', min = 0, max = 1},
+ #ref{name = rsm_last, label = '$last', min = 0, max = 1},
+ #ref{name = rsm_max, label = '$max', min = 0, max = 1}]}).
+
+-xml(mam_start,
+ #elem{name = <<"start">>,
+ xmlns = <<"urn:xmpp:mam:tmp">>,
+ result = '$cdata',
+ cdata = #cdata{required = true,
+ dec = {dec_utc, []},
+ enc = {enc_utc, []}}}).
+
+-xml(mam_end,
+ #elem{name = <<"end">>,
+ xmlns = <<"urn:xmpp:mam:tmp">>,
+ result = '$cdata',
+ cdata = #cdata{required = true,
+ dec = {dec_utc, []},
+ enc = {enc_utc, []}}}).
+
+-xml(mam_with,
+ #elem{name = <<"with">>,
+ xmlns = <<"urn:xmpp:mam:tmp">>,
+ result = '$cdata',
+ cdata = #cdata{required = true,
+ dec = {dec_jid, []},
+ enc = {enc_jid, []}}}).
+
+-xml(mam_query,
+ #elem{name = <<"query">>,
+ xmlns = [<<"urn:xmpp:mam:0">>, <<"urn:xmpp:mam:tmp">>],
+ result = {mam_query, '$xmlns', '$id', '$start', '$end', '$with',
+ '$rsm', '$xdata'},
+ attrs = [#attr{name = <<"queryid">>, label = '$id'},
+ #attr{name = <<"xmlns">>}],
+ refs = [#ref{name = mam_start, min = 0, max = 1, label = '$start'},
+ #ref{name = mam_end, min = 0, max = 1, label = '$end'},
+ #ref{name = mam_with, min = 0, max = 1, label = '$with'},
+ #ref{name = rsm_set, min = 0, max = 1, label = '$rsm'},
+ #ref{name = xdata, min = 0, max = 1, label = '$xdata'}]}).
+
+-xml(mam_archived,
+ #elem{name = <<"archived">>,
+ xmlns = <<"urn:xmpp:mam:tmp">>,
+ result = {mam_archived, '$by', '$id'},
+ attrs = [#attr{name = <<"id">>},
+ #attr{name = <<"by">>,
+ required = true,
+ dec = {dec_jid, []},
+ enc = {enc_jid, []}}]}).
+
+-xml(mam_result,
+ #elem{name = <<"result">>,
+ xmlns = [<<"urn:xmpp:mam:0">>, <<"urn:xmpp:mam:tmp">>],
+ result = {mam_result, '$xmlns', '$queryid', '$id', '$_els'},
+ attrs = [#attr{name = <<"queryid">>},
+ #attr{name = <<"xmlns">>},
+ #attr{name = <<"id">>}]}).
+
+-xml(mam_jid,
+ #elem{name = <<"jid">>,
+ xmlns = <<"urn:xmpp:mam:tmp">>,
+ result = '$cdata',
+ cdata = #cdata{required = true,
+ dec = {dec_jid, []},
+ enc = {enc_jid, []}}}).
+
+-xml(mam_never,
+ #elem{name = <<"never">>,
+ xmlns = <<"urn:xmpp:mam:tmp">>,
+ result = '$jids',
+ refs = [#ref{name = mam_jid, label = '$jids', default = []}]}).
+
+-xml(mam_always,
+ #elem{name = <<"always">>,
+ xmlns = <<"urn:xmpp:mam:tmp">>,
+ result = '$jids',
+ refs = [#ref{name = mam_jid, label = '$jids', default = []}]}).
+
+-xml(mam_prefs,
+ #elem{name = <<"prefs">>,
+ xmlns = [<<"urn:xmpp:mam:0">>, <<"urn:xmpp:mam:tmp">>],
+ result = {mam_prefs, '$xmlns', '$default', '$always', '$never'},
+ attrs = [#attr{name = <<"default">>,
+ dec = {dec_enum, [[always, never, roster]]},
+ enc = {enc_enum, []}},
+ #attr{name = <<"xmlns">>}],
+ refs = [#ref{name = mam_always, label = '$always',
+ min = 0, max = 1, default = []},
+ #ref{name = mam_never, label = '$never',
+ min = 0, max = 1, default = []}]}).
+
+-xml(mam_fin,
+ #elem{name = <<"fin">>,
+ xmlns = <<"urn:xmpp:mam:0">>,
+ result = {mam_fin, '$id', '$rsm'},
+ attrs = [#attr{name = <<"queryid">>, label = '$id'}],
+ refs = [#ref{name = rsm_set, min = 0, max = 1, label = '$rsm'}]}).
+
-xml(forwarded,
#elem{name = <<"forwarded">>,
xmlns = <<"urn:xmpp:forward:0">>,