From 0bcbd12776a03902f356c3ac48465cc901670393 Mon Sep 17 00:00:00 2001 From: Evgeniy Khramtsov Date: Sun, 31 Jul 2016 08:51:47 +0300 Subject: [PATCH] Rewrite mod_mix to use XML generator --- include/xmpp_codec.hrl | 104 ++++---- src/mod_mix.erl | 116 +++----- src/mod_muc_room.erl | 3 +- src/xmpp.erl | 20 +- src/xmpp_codec.erl | 591 +++++++++++++++++++---------------------- tools/xmpp_codec.spec | 24 +- 6 files changed, 383 insertions(+), 475 deletions(-) diff --git a/include/xmpp_codec.hrl b/include/xmpp_codec.hrl index caabb101d..acbc81e4a 100644 --- a/include/xmpp_codec.hrl +++ b/include/xmpp_codec.hrl @@ -15,6 +15,14 @@ 'no-permanent-store' | 'no-permanent-storage'}). -type hint() :: #hint{}. +-record(iq, {id :: binary(), + type :: 'error' | 'get' | 'result' | 'set', + lang :: binary(), + from :: any(), + to :: any(), + sub_els = [] :: [any()]}). +-type iq() :: #iq{}. + -record(feature_register, {}). -type feature_register() :: #feature_register{}. @@ -170,6 +178,14 @@ -record(private, {xml_els = [] :: [any()]}). -type private() :: #private{}. +-record(db_verify, {from :: any(), + to :: any(), + id :: binary(), + type :: 'error' | 'invalid' | 'valid', + key = <<>> :: binary(), + sub_els = [] :: [any()]}). +-type db_verify() :: #db_verify{}. + -record(nick, {name :: binary()}). -type nick() :: #nick{}. @@ -267,6 +283,17 @@ jid :: any()}). -type pubsub_subscribe() :: #pubsub_subscribe{}. +-record(message, {id :: binary(), + type = normal :: 'chat' | 'error' | 'groupchat' | 'headline' | 'normal', + lang :: binary(), + from :: any(), + to :: any(), + subject = [] :: [#text{}], + body = [] :: [#text{}], + thread :: binary(), + sub_els = [] :: [any()]}). +-type message() :: #message{}. + -record(sasl_auth, {mechanism :: binary(), text :: any()}). -type sasl_auth() :: #sasl_auth{}. @@ -349,6 +376,17 @@ items = [] :: [#pubsub_item{}]}). -type pubsub_items() :: #pubsub_items{}. +-record(presence, {id :: binary(), + type = available :: 'available' | 'error' | 'probe' | 'subscribe' | 'subscribed' | 'unavailable' | 'unsubscribe' | 'unsubscribed', + lang :: binary(), + from :: any(), + to :: any(), + show :: 'away' | 'chat' | 'dnd' | 'xa', + status = [] :: [#text{}], + priority :: integer(), + sub_els = [] :: [any()]}). +-type presence() :: #presence{}. + -record(sic, {ip :: any(), port :: non_neg_integer(), xmlns :: binary()}). @@ -385,6 +423,13 @@ userid :: binary()}). -type vcard_email() :: #vcard_email{}. +-record(db_result, {from :: any(), + to :: any(), + type :: 'error' | 'invalid' | 'valid', + key = <<>> :: binary(), + sub_els = [] :: [any()]}). +-type db_result() :: #db_result{}. + -record(carbons_received, {forwarded :: #forwarded{}}). -type carbons_received() :: #carbons_received{}. @@ -729,57 +774,10 @@ code :: non_neg_integer(), by :: binary(), reason :: atom() | #gone{} | #redirect{}, - text :: #text{}}). + text :: #text{}, + sub_els = [] :: [any()]}). -type error() :: #error{}. --record(db_verify, {from :: any(), - to :: any(), - id :: binary(), - type :: 'error' | 'invalid' | 'valid', - key = <<>> :: binary(), - error :: #error{}}). --type db_verify() :: #db_verify{}. - --record(db_result, {from :: any(), - to :: any(), - type :: 'error' | 'invalid' | 'valid', - key = <<>> :: binary(), - error :: #error{}}). --type db_result() :: #db_result{}. - --record(presence, {id :: binary(), - type = available :: 'available' | 'error' | 'probe' | 'subscribe' | 'subscribed' | 'unavailable' | 'unsubscribe' | 'unsubscribed', - lang :: binary(), - from :: any(), - to :: any(), - show :: 'away' | 'chat' | 'dnd' | 'xa', - status = [] :: [#text{}], - priority :: integer(), - error :: #error{}, - sub_els = [] :: [any()]}). --type presence() :: #presence{}. - --record(message, {id :: binary(), - type = normal :: 'chat' | 'error' | 'groupchat' | 'headline' | 'normal', - lang :: binary(), - from :: any(), - to :: any(), - subject = [] :: [#text{}], - body = [] :: [#text{}], - thread :: binary(), - error :: #error{}, - sub_els = [] :: [any()]}). --type message() :: #message{}. - --record(iq, {id :: binary(), - type :: 'error' | 'get' | 'result' | 'set', - lang :: binary(), - from :: any(), - to :: any(), - error :: #error{}, - sub_els = [] :: [any()]}). --type iq() :: #iq{}. - -record(mix_join, {jid :: any(), subscribe = [] :: [binary()]}). -type mix_join() :: #mix_join{}. @@ -861,6 +859,7 @@ mam_archived() | p1_rebind() | sasl_abort() | + db_result() | carbons_received() | pubsub_retract() | upload_slot() | @@ -868,7 +867,6 @@ compressed() | block_list() | rsm_set() | - db_result() | 'see-other-host'() | hint() | stream_start() | @@ -939,8 +937,8 @@ mix_join() | xmpp_session() | xdata() | - xcaptcha() | iq() | + xcaptcha() | streamhost() | bind() | last() | @@ -971,9 +969,9 @@ muc_destroy() | vcard_key() | csi() | + db_verify() | roster_query() | mam_query() | - db_verify() | bookmark_url() | vcard_email() | vcard_label() | @@ -992,8 +990,8 @@ muc_unique() | sasl_response() | pubsub_subscribe() | - presence() | message() | + presence() | gone() | sm_resume() | carbons_enable() | diff --git a/src/mod_mix.erl b/src/mod_mix.erl index b373ad13d..3ba173b9f 100644 --- a/src/mod_mix.erl +++ b/src/mod_mix.erl @@ -12,7 +12,7 @@ -behaviour(gen_mod). %% API --export([start_link/2, start/2, stop/1, process_iq/3, +-export([start_link/2, start/2, stop/1, process_iq/1, disco_items/5, disco_identity/5, disco_info/5, disco_features/5, mod_opt_type/1, depends/2]). @@ -21,8 +21,7 @@ terminate/2, code_change/3]). -include("logger.hrl"). --include("jlib.hrl"). --include("pubsub.hrl"). +-include("xmpp.hrl"). -define(PROCNAME, ejabberd_mod_mix). -define(NODES, [?NS_MIX_NODES_MESSAGES, @@ -57,84 +56,59 @@ disco_features(_Acc, _From, _To, _Node, _Lang) -> {result, [?NS_MIX_0]}. disco_items(_Acc, _From, To, _Node, _Lang) when To#jid.luser /= <<"">> -> - To_s = jid:to_string(jid:remove_resource(To)), - {result, [#xmlel{name = <<"item">>, - attrs = [{<<"jid">>, To_s}, - {<<"node">>, Node}]} || Node <- ?NODES]}; + BareTo = jid:remove_resource(To), + {result, [#disco_item{jid = BareTo, node = Node} || Node <- ?NODES]}; disco_items(_Acc, _From, _To, _Node, _Lang) -> {result, []}. disco_identity(Acc, _From, To, _Node, _Lang) when To#jid.luser == <<"">> -> - Acc ++ [#xmlel{name = <<"identity">>, - attrs = - [{<<"category">>, <<"conference">>}, - {<<"name">>, <<"MIX service">>}, - {<<"type">>, <<"text">>}]}]; + Acc ++ [#identity{category = <<"conference">>, + name = <<"MIX service">>, + type = <<"text">>}]; disco_identity(Acc, _From, _To, _Node, _Lang) -> - Acc ++ [#xmlel{name = <<"identity">>, - attrs = - [{<<"category">>, <<"conference">>}, - {<<"type">>, <<"mix">>}]}]. + Acc ++ [#identity{category = <<"conference">>, + type = <<"mix">>}]. disco_info(_Acc, _From, To, _Node, _Lang) when is_atom(To) -> - [#xmlel{name = <<"x">>, - attrs = [{<<"xmlns">>, ?NS_XDATA}, - {<<"type">>, <<"result">>}], - children = [#xmlel{name = <<"field">>, - attrs = [{<<"var">>, <<"FORM_TYPE">>}, - {<<"type">>, <<"hidden">>}], - children = [#xmlel{name = <<"value">>, - children = [{xmlcdata, - ?NS_MIX_SERVICEINFO_0}]}]}]}]; + [#xdata{type = result, + fields = [#xdata_field{var = <<"FORM_TYPE">>, + type = hidden, + values = [?NS_MIX_SERVICEINFO_0]}]}]; disco_info(Acc, _From, _To, _Node, _Lang) -> Acc. -process_iq(From, To, - #iq{type = set, sub_el = #xmlel{name = <<"join">>} = SubEl} = IQ) -> - Nodes = lists:flatmap( - fun(#xmlel{name = <<"subscribe">>, attrs = Attrs}) -> - Node = fxml:get_attr_s(<<"node">>, Attrs), - case lists:member(Node, ?NODES) of - true -> [Node]; - false -> [] - end; - (_) -> - [] - end, SubEl#xmlel.children), +process_iq(#iq{type = set, from = From, to = To, + sub_els = [#mix_join{subscribe = SubNodes}]} = IQ) -> + Nodes = [Node || Node <- SubNodes, lists:member(Node, ?NODES)], case subscribe_nodes(From, To, Nodes) of {result, _} -> case publish_participant(From, To) of {result, _} -> - LFrom_s = jid:to_string(jid:tolower(jid:remove_resource(From))), - Subscribe = [#xmlel{name = <<"subscribe">>, - attrs = [{<<"node">>, Node}]} || Node <- Nodes], - IQ#iq{type = result, - sub_el = [#xmlel{name = <<"join">>, - attrs = [{<<"jid">>, LFrom_s}, - {<<"xmlns">>, ?NS_MIX_0}], - children = Subscribe}]}; + BareFrom = jid:remove_resource(From), + xmpp:make_iq_result( + IQ, #mix_join{jid = BareFrom, subscribe = Nodes}); {error, Err} -> - IQ#iq{type = error, sub_el = [SubEl, Err]} + xmpp:make_error(IQ, Err) end; {error, Err} -> - IQ#iq{type = error, sub_el = [SubEl, Err]} + xmpp:make_error(IQ, Err) end; -process_iq(From, To, - #iq{type = set, sub_el = #xmlel{name = <<"leave">>} = SubEl} = IQ) -> +process_iq(#iq{type = set, from = From, to = To, + sub_els = [#mix_leave{}]} = IQ) -> case delete_participant(From, To) of {result, _} -> case unsubscribe_nodes(From, To, ?NODES) of {result, _} -> - IQ#iq{type = result, sub_el = []}; + xmpp:make_iq_result(IQ); {error, Err} -> - IQ#iq{type = error, sub_el = [SubEl, Err]} + xmpp:make_error(IQ, Err) end; {error, Err} -> - IQ#iq{type = error, sub_el = [SubEl, Err]} + xmpp:make_error(IQ, Err) end; -process_iq(_From, _To, #iq{sub_el = SubEl, lang = Lang} = IQ) -> +process_iq(#iq{lang = Lang} = IQ) -> Txt = <<"Unsupported MIX query">>, - IQ#iq{type = error, sub_el = [SubEl, ?ERRT_BAD_REQUEST(Lang, Txt)]}. + xmpp:make_error(IQ, xmpp:err_bad_request(Txt, Lang)). %%%=================================================================== %%% gen_server callbacks @@ -185,8 +159,8 @@ handle_info({route, From, To, Packet}, State) -> try ?ERROR_MSG("failed to route packet ~p from '~s' to '~s': ~p", [Packet, jid:to_string(From), jid:to_string(To), Err]), - ErrPkt = jlib:make_error_reply(Packet, ?ERR_INTERNAL_SERVER_ERROR), - ejabberd_router:route_error(To, From, ErrPkt, Packet) + Error = xmpp:err_internal_server_error(), + ejabberd_router:route_error(To, From, Packet, Error) catch _:_ -> ok end; @@ -220,20 +194,11 @@ code_change(_OldVsn, State, _Extra) -> %%%=================================================================== %%% Internal functions %%%=================================================================== -do_route(_State, From, To, #xmlel{name = <<"iq">>} = Packet) -> - if To#jid.luser == <<"">> -> - ejabberd_local:process_iq(From, To, Packet); - true -> - ejabberd_sm:process_iq(From, To, Packet) - end; -do_route(_State, From, To, #xmlel{name = <<"presence">>} = Packet) +do_route(_State, From, To, #iq{} = Packet) -> + ejabberd_router:process_iq(From, To, Packet); +do_route(_State, From, To, #presence{type = unavailable}) when To#jid.luser /= <<"">> -> - case fxml:get_tag_attr_s(<<"type">>, Packet) of - <<"unavailable">> -> - delete_presence(From, To); - _ -> - ok - end; + delete_presence(From, To); do_route(_State, _From, _To, _Packet) -> ok. @@ -284,15 +249,14 @@ unsubscribe_nodes(From, To, Nodes) -> end, {result, []}, Nodes). publish_participant(From, To) -> - LFrom = jid:tolower(jid:remove_resource(From)), + BareFrom = jid:remove_resource(From), + LFrom = jid:tolower(BareFrom), LTo = jid:tolower(jid:remove_resource(To)), - Participant = #xmlel{name = <<"participant">>, - attrs = [{<<"xmlns">>, ?NS_MIX_0}, - {<<"jid">>, jid:to_string(LFrom)}]}, + Participant = #mix_participant{jid = BareFrom}, ItemID = p1_sha:sha(jid:to_string(LFrom)), mod_pubsub:publish_item( LTo, To#jid.lserver, ?NS_MIX_NODES_PARTICIPANTS, - From, ItemID, [Participant]). + From, ItemID, [xmpp:encode(Participant)]). delete_presence(From, To) -> LFrom = jid:tolower(From), @@ -300,8 +264,8 @@ delete_presence(From, To) -> case mod_pubsub:get_items(LTo, ?NS_MIX_NODES_PRESENCE) of Items when is_list(Items) -> lists:foreach( - fun(#pubsub_item{modification = {_, LJID}, - itemid = {ItemID, _}}) when LJID == LFrom -> + fun({pubsub_item, {ItemID, _}, _, {_, LJID}, _}) + when LJID == LFrom -> delete_item(From, To, ?NS_MIX_NODES_PRESENCE, ItemID); (_) -> ok diff --git a/src/mod_muc_room.erl b/src/mod_muc_room.erl index a539ab848..68064fcb7 100644 --- a/src/mod_muc_room.erl +++ b/src/mod_muc_room.erl @@ -1110,8 +1110,9 @@ change_stanzaid(ToJID, #iq{id = PreviousId} = Packet) -> -spec decide_fate_message(message(), jid(), state()) -> continue_delivery | forget_message | {expulse_sender, binary()}. -decide_fate_message(#message{type = error, error = Err}, +decide_fate_message(#message{type = error} = Msg, From, StateData) -> + Err = xmpp:get_error(Msg), PD = case check_error_kick(Err) of %% If this is an error stanza and its condition matches a criteria true -> diff --git a/src/xmpp.erl b/src/xmpp.erl index 6e8145190..a927a6a9a 100644 --- a/src/xmpp.erl +++ b/src/xmpp.erl @@ -88,10 +88,10 @@ make_iq_result(#iq{type = Type, from = From, to = To} = IQ, El) end, IQ#iq{type = result, to = From, from = To, sub_els = SubEls}. --spec make_error(message(), error()) -> message(); - (presence(), error()) -> presence(); - (iq(), error()) -> iq(); - (xmlel(), error()) -> xmlel(). +-spec make_error(message(), error() | xmlel()) -> message(); + (presence(), error() | xmlel()) -> presence(); + (iq(), error() | xmlel()) -> iq(); + (xmlel(), error() | xmlel()) -> xmlel(). make_error(#message{type = Type, from = From, to = To, sub_els = Els} = Msg, Err) when Type /= error -> Msg#message{type = error, from = To, to = From, sub_els = Els ++ [Err]}; @@ -159,9 +159,11 @@ get_to(#message{to = J}) -> J; get_to(#presence{to = J}) -> J. -spec get_error(iq() | message() | presence()) -> undefined | error(). -get_error(#iq{error = E}) -> E; -get_error(#message{error = E}) -> E; -get_error(#presence{error = E}) -> E. +get_error(Stanza) -> + case get_subtag(Stanza, #error{}) of + false -> undefined; + Error -> Error + end. -spec get_els(iq() | message() | presence()) -> [xmpp_element() | xmlel()]; (xmlel()) -> [xmlel()]. @@ -215,9 +217,7 @@ set_from_to(#presence{} = Pres, F, T) -> Pres#presence{from = F, to = T}. -spec set_error(iq(), error()) -> iq(); (message(), error()) -> message(); (presence(), error()) -> presence(). -set_error(#iq{} = IQ, E) -> IQ#iq{error = E}; -set_error(#message{} = Msg, E) -> Msg#message{error = E}; -set_error(#presence{} = Pres, E) -> Pres#presence{error = E}. +set_error(Stanza, E) -> set_subtag(Stanza, E). -spec set_els(iq(), [xmpp_element() | xmlel()]) -> iq(); (message(), [xmpp_element() | xmlel()]) -> message(); diff --git a/src/xmpp_codec.erl b/src/xmpp_codec.erl index 8d87712df..6fddf97ed 100644 --- a/src/xmpp_codec.erl +++ b/src/xmpp_codec.erl @@ -2230,13 +2230,13 @@ encode({stats, _} = Query) -> encode_stats(Query, [{<<"xmlns">>, <<"http://jabber.org/protocol/stats">>}]); -encode({iq, _, _, _, _, _, _, _} = Iq) -> +encode({iq, _, _, _, _, _, _} = Iq) -> encode_iq(Iq, [{<<"xmlns">>, <<"jabber:client">>}]); -encode({message, _, _, _, _, _, _, _, _, _, _} = +encode({message, _, _, _, _, _, _, _, _, _} = Message) -> encode_message(Message, [{<<"xmlns">>, <<"jabber:client">>}]); -encode({presence, _, _, _, _, _, _, _, _, _, _} = +encode({presence, _, _, _, _, _, _, _, _, _} = Presence) -> encode_presence(Presence, [{<<"xmlns">>, <<"jabber:client">>}]); @@ -2248,7 +2248,7 @@ encode({redirect, _} = Redirect) -> encode_error_redirect(Redirect, [{<<"xmlns">>, <<"urn:ietf:params:xml:ns:xmpp-stanzas">>}]); -encode({error, _, _, _, _, _} = Error) -> +encode({error, _, _, _, _, _, _} = Error) -> encode_error(Error, [{<<"xmlns">>, <<"jabber:client">>}]); encode({bind, _, _} = Bind) -> @@ -2736,14 +2736,14 @@ get_name({bookmark_url, _, _}) -> <<"url">>; get_name({bookmark_storage, _, _}) -> <<"storage">>; get_name({stat, _, _, _, _}) -> <<"stat">>; get_name({stats, _}) -> <<"query">>; -get_name({iq, _, _, _, _, _, _, _}) -> <<"iq">>; -get_name({message, _, _, _, _, _, _, _, _, _, _}) -> +get_name({iq, _, _, _, _, _, _}) -> <<"iq">>; +get_name({message, _, _, _, _, _, _, _, _, _}) -> <<"message">>; -get_name({presence, _, _, _, _, _, _, _, _, _, _}) -> +get_name({presence, _, _, _, _, _, _, _, _, _}) -> <<"presence">>; get_name({gone, _}) -> <<"gone">>; get_name({redirect, _}) -> <<"redirect">>; -get_name({error, _, _, _, _, _}) -> <<"error">>; +get_name({error, _, _, _, _, _, _}) -> <<"error">>; get_name({bind, _, _}) -> <<"bind">>; get_name({legacy_auth, _, _, _, _}) -> <<"query">>; get_name({sasl_auth, _, _}) -> <<"auth">>; @@ -2943,17 +2943,17 @@ get_ns({stat, _, _, _, _}) -> <<"http://jabber.org/protocol/stats">>; get_ns({stats, _}) -> <<"http://jabber.org/protocol/stats">>; -get_ns({iq, _, _, _, _, _, _, _}) -> +get_ns({iq, _, _, _, _, _, _}) -> <<"jabber:client">>; +get_ns({message, _, _, _, _, _, _, _, _, _}) -> <<"jabber:client">>; -get_ns({message, _, _, _, _, _, _, _, _, _, _}) -> - <<"jabber:client">>; -get_ns({presence, _, _, _, _, _, _, _, _, _, _}) -> +get_ns({presence, _, _, _, _, _, _, _, _, _}) -> <<"jabber:client">>; get_ns({gone, _}) -> <<"urn:ietf:params:xml:ns:xmpp-stanzas">>; get_ns({redirect, _}) -> <<"urn:ietf:params:xml:ns:xmpp-stanzas">>; -get_ns({error, _, _, _, _, _}) -> <<"jabber:client">>; +get_ns({error, _, _, _, _, _, _}) -> + <<"jabber:client">>; get_ns({bind, _, _}) -> <<"urn:ietf:params:xml:ns:xmpp-bind">>; get_ns({legacy_auth, _, _, _, _}) -> @@ -3256,16 +3256,16 @@ pp(bookmark_url, 2) -> [name, url]; pp(bookmark_storage, 2) -> [conference, url]; pp(stat, 4) -> [name, units, value, error]; pp(stats, 1) -> [stat]; -pp(iq, 7) -> [id, type, lang, from, to, error, sub_els]; -pp(message, 10) -> - [id, type, lang, from, to, subject, body, thread, error, +pp(iq, 6) -> [id, type, lang, from, to, sub_els]; +pp(message, 9) -> + [id, type, lang, from, to, subject, body, thread, sub_els]; -pp(presence, 10) -> +pp(presence, 9) -> [id, type, lang, from, to, show, status, priority, - error, sub_els]; + sub_els]; pp(gone, 1) -> [uri]; pp(redirect, 1) -> [uri]; -pp(error, 5) -> [type, code, by, reason, text]; +pp(error, 6) -> [type, code, by, reason, text, sub_els]; pp(bind, 2) -> [jid, resource]; pp(legacy_auth, 4) -> [username, password, digest, resource]; @@ -3419,8 +3419,8 @@ pp(adhoc_note, 2) -> [type, data]; pp(adhoc_command, 8) -> [node, action, sid, status, lang, actions, notes, xdata]; -pp(db_result, 5) -> [from, to, type, key, error]; -pp(db_verify, 6) -> [from, to, id, type, key, error]; +pp(db_result, 5) -> [from, to, type, key, sub_els]; +pp(db_verify, 6) -> [from, to, id, type, key, sub_els]; pp(handshake, 1) -> [data]; pp(stream_start, 8) -> [from, to, id, version, xmlns, stream_xmlns, db_xmlns, @@ -4789,39 +4789,36 @@ encode_handshake_cdata(_val, _acc) -> decode_db_verify(__TopXMLNS, __IgnoreEls, {xmlel, <<"db:verify">>, _attrs, _els}) -> - {Key, Error} = decode_db_verify_els(__TopXMLNS, - __IgnoreEls, _els, <<>>, undefined), + {Key, __Els} = decode_db_verify_els(__TopXMLNS, + __IgnoreEls, _els, <<>>, []), {From, To, Id, Type} = decode_db_verify_attrs(__TopXMLNS, _attrs, undefined, undefined, undefined, undefined), - {db_verify, From, To, Id, Type, Key, Error}. + {db_verify, From, To, Id, Type, Key, __Els}. decode_db_verify_els(__TopXMLNS, __IgnoreEls, [], Key, - Error) -> - {decode_db_verify_cdata(__TopXMLNS, Key), Error}; + __Els) -> + {decode_db_verify_cdata(__TopXMLNS, Key), + lists:reverse(__Els)}; decode_db_verify_els(__TopXMLNS, __IgnoreEls, - [{xmlcdata, _data} | _els], Key, Error) -> + [{xmlcdata, _data} | _els], Key, __Els) -> decode_db_verify_els(__TopXMLNS, __IgnoreEls, _els, - <>, Error); + <>, __Els); decode_db_verify_els(__TopXMLNS, __IgnoreEls, - [{xmlel, <<"error">>, _attrs, _} = _el | _els], Key, - Error) -> - case get_attr(<<"xmlns">>, _attrs) of - <<"">> when __TopXMLNS == <<"jabber:client">> -> - decode_db_verify_els(__TopXMLNS, __IgnoreEls, _els, Key, - decode_error(__TopXMLNS, __IgnoreEls, _el)); - <<"jabber:client">> -> - decode_db_verify_els(__TopXMLNS, __IgnoreEls, _els, Key, - decode_error(<<"jabber:client">>, __IgnoreEls, - _el)); - _ -> - decode_db_verify_els(__TopXMLNS, __IgnoreEls, _els, Key, - Error) - end; -decode_db_verify_els(__TopXMLNS, __IgnoreEls, - [_ | _els], Key, Error) -> - decode_db_verify_els(__TopXMLNS, __IgnoreEls, _els, Key, - Error). + [{xmlel, _, _, _} = _el | _els], Key, __Els) -> + if __IgnoreEls -> + decode_db_verify_els(__TopXMLNS, __IgnoreEls, _els, Key, + [_el | __Els]); + true -> + case is_known_tag(_el) of + true -> + decode_db_verify_els(__TopXMLNS, __IgnoreEls, _els, Key, + [decode(_el) | __Els]); + false -> + decode_db_verify_els(__TopXMLNS, __IgnoreEls, _els, Key, + __Els) + end + end. decode_db_verify_attrs(__TopXMLNS, [{<<"from">>, _val} | _attrs], _From, To, Id, Type) -> @@ -4851,11 +4848,10 @@ decode_db_verify_attrs(__TopXMLNS, [], From, To, Id, decode_db_verify_attr_type(__TopXMLNS, Type)}. encode_db_verify({db_verify, From, To, Id, Type, Key, - Error}, + __Els}, _xmlns_attrs) -> - _els = lists:reverse(encode_db_verify_cdata(Key, - 'encode_db_verify_$error'(Error, - []))), + _els = [encode(_el) || _el <- __Els] ++ + encode_db_verify_cdata(Key, []), _attrs = encode_db_verify_attr_type(Type, encode_db_verify_attr_id(Id, encode_db_verify_attr_to(To, @@ -4863,10 +4859,6 @@ encode_db_verify({db_verify, From, To, Id, Type, Key, _xmlns_attrs)))), {xmlel, <<"db:verify">>, _attrs, _els}. -'encode_db_verify_$error'(undefined, _acc) -> _acc; -'encode_db_verify_$error'(Error, _acc) -> - [encode_error(Error, []) | _acc]. - decode_db_verify_attr_from(__TopXMLNS, undefined) -> erlang:error({xmpp_codec, {missing_attr, <<"from">>, <<"db:verify">>, @@ -4930,39 +4922,36 @@ encode_db_verify_cdata(_val, _acc) -> decode_db_result(__TopXMLNS, __IgnoreEls, {xmlel, <<"db:result">>, _attrs, _els}) -> - {Key, Error} = decode_db_result_els(__TopXMLNS, - __IgnoreEls, _els, <<>>, undefined), + {Key, __Els} = decode_db_result_els(__TopXMLNS, + __IgnoreEls, _els, <<>>, []), {From, To, Type} = decode_db_result_attrs(__TopXMLNS, _attrs, undefined, undefined, undefined), - {db_result, From, To, Type, Key, Error}. + {db_result, From, To, Type, Key, __Els}. decode_db_result_els(__TopXMLNS, __IgnoreEls, [], Key, - Error) -> - {decode_db_result_cdata(__TopXMLNS, Key), Error}; + __Els) -> + {decode_db_result_cdata(__TopXMLNS, Key), + lists:reverse(__Els)}; decode_db_result_els(__TopXMLNS, __IgnoreEls, - [{xmlcdata, _data} | _els], Key, Error) -> + [{xmlcdata, _data} | _els], Key, __Els) -> decode_db_result_els(__TopXMLNS, __IgnoreEls, _els, - <>, Error); + <>, __Els); decode_db_result_els(__TopXMLNS, __IgnoreEls, - [{xmlel, <<"error">>, _attrs, _} = _el | _els], Key, - Error) -> - case get_attr(<<"xmlns">>, _attrs) of - <<"">> when __TopXMLNS == <<"jabber:client">> -> - decode_db_result_els(__TopXMLNS, __IgnoreEls, _els, Key, - decode_error(__TopXMLNS, __IgnoreEls, _el)); - <<"jabber:client">> -> - decode_db_result_els(__TopXMLNS, __IgnoreEls, _els, Key, - decode_error(<<"jabber:client">>, __IgnoreEls, - _el)); - _ -> - decode_db_result_els(__TopXMLNS, __IgnoreEls, _els, Key, - Error) - end; -decode_db_result_els(__TopXMLNS, __IgnoreEls, - [_ | _els], Key, Error) -> - decode_db_result_els(__TopXMLNS, __IgnoreEls, _els, Key, - Error). + [{xmlel, _, _, _} = _el | _els], Key, __Els) -> + if __IgnoreEls -> + decode_db_result_els(__TopXMLNS, __IgnoreEls, _els, Key, + [_el | __Els]); + true -> + case is_known_tag(_el) of + true -> + decode_db_result_els(__TopXMLNS, __IgnoreEls, _els, Key, + [decode(_el) | __Els]); + false -> + decode_db_result_els(__TopXMLNS, __IgnoreEls, _els, Key, + __Els) + end + end. decode_db_result_attrs(__TopXMLNS, [{<<"from">>, _val} | _attrs], _From, To, Type) -> @@ -4987,21 +4976,16 @@ decode_db_result_attrs(__TopXMLNS, [], From, To, decode_db_result_attr_type(__TopXMLNS, Type)}. encode_db_result({db_result, From, To, Type, Key, - Error}, + __Els}, _xmlns_attrs) -> - _els = lists:reverse(encode_db_result_cdata(Key, - 'encode_db_result_$error'(Error, - []))), + _els = [encode(_el) || _el <- __Els] ++ + encode_db_result_cdata(Key, []), _attrs = encode_db_result_attr_type(Type, encode_db_result_attr_to(To, encode_db_result_attr_from(From, _xmlns_attrs))), {xmlel, <<"db:result">>, _attrs, _els}. -'encode_db_result_$error'(undefined, _acc) -> _acc; -'encode_db_result_$error'(Error, _acc) -> - [encode_error(Error, []) | _acc]. - decode_db_result_attr_from(__TopXMLNS, undefined) -> erlang:error({xmpp_codec, {missing_attr, <<"from">>, <<"db:result">>, @@ -23335,329 +23319,363 @@ encode_bind_jid_cdata(_val, _acc) -> decode_error(__TopXMLNS, __IgnoreEls, {xmlel, <<"error">>, _attrs, _els}) -> - {Text, Reason} = decode_error_els(__TopXMLNS, - __IgnoreEls, _els, undefined, undefined), + {Text, Reason, __Els} = decode_error_els(__TopXMLNS, + __IgnoreEls, _els, undefined, + undefined, []), {Type, Code, By} = decode_error_attrs(__TopXMLNS, _attrs, undefined, undefined, undefined), - {error, Type, Code, By, Reason, Text}. + {error, Type, Code, By, Reason, Text, __Els}. decode_error_els(__TopXMLNS, __IgnoreEls, [], Text, - Reason) -> - {Text, Reason}; + Reason, __Els) -> + {Text, Reason, lists:reverse(__Els)}; decode_error_els(__TopXMLNS, __IgnoreEls, [{xmlel, <<"text">>, _attrs, _} = _el | _els], Text, - Reason) -> + Reason, __Els) -> case get_attr(<<"xmlns">>, _attrs) of <<"urn:ietf:params:xml:ns:xmpp-stanzas">> -> decode_error_els(__TopXMLNS, __IgnoreEls, _els, decode_error_text(<<"urn:ietf:params:xml:ns:xmpp-stanzas">>, __IgnoreEls, _el), - Reason); + Reason, __Els); _ -> decode_error_els(__TopXMLNS, __IgnoreEls, _els, Text, - Reason) + Reason, __Els) end; decode_error_els(__TopXMLNS, __IgnoreEls, [{xmlel, <<"bad-request">>, _attrs, _} = _el | _els], - Text, Reason) -> + Text, Reason, __Els) -> case get_attr(<<"xmlns">>, _attrs) of <<"urn:ietf:params:xml:ns:xmpp-stanzas">> -> decode_error_els(__TopXMLNS, __IgnoreEls, _els, Text, decode_error_bad_request(<<"urn:ietf:params:xml:ns:xmpp-stanzas">>, - __IgnoreEls, _el)); + __IgnoreEls, _el), + __Els); _ -> decode_error_els(__TopXMLNS, __IgnoreEls, _els, Text, - Reason) + Reason, __Els) end; decode_error_els(__TopXMLNS, __IgnoreEls, [{xmlel, <<"conflict">>, _attrs, _} = _el | _els], Text, - Reason) -> + Reason, __Els) -> case get_attr(<<"xmlns">>, _attrs) of <<"urn:ietf:params:xml:ns:xmpp-stanzas">> -> decode_error_els(__TopXMLNS, __IgnoreEls, _els, Text, decode_error_conflict(<<"urn:ietf:params:xml:ns:xmpp-stanzas">>, - __IgnoreEls, _el)); + __IgnoreEls, _el), + __Els); _ -> decode_error_els(__TopXMLNS, __IgnoreEls, _els, Text, - Reason) + Reason, __Els) end; decode_error_els(__TopXMLNS, __IgnoreEls, [{xmlel, <<"feature-not-implemented">>, _attrs, _} = _el | _els], - Text, Reason) -> + Text, Reason, __Els) -> case get_attr(<<"xmlns">>, _attrs) of <<"urn:ietf:params:xml:ns:xmpp-stanzas">> -> decode_error_els(__TopXMLNS, __IgnoreEls, _els, Text, decode_error_feature_not_implemented(<<"urn:ietf:params:xml:ns:xmpp-stanzas">>, __IgnoreEls, - _el)); + _el), + __Els); _ -> decode_error_els(__TopXMLNS, __IgnoreEls, _els, Text, - Reason) + Reason, __Els) end; decode_error_els(__TopXMLNS, __IgnoreEls, [{xmlel, <<"forbidden">>, _attrs, _} = _el | _els], - Text, Reason) -> + Text, Reason, __Els) -> case get_attr(<<"xmlns">>, _attrs) of <<"urn:ietf:params:xml:ns:xmpp-stanzas">> -> decode_error_els(__TopXMLNS, __IgnoreEls, _els, Text, decode_error_forbidden(<<"urn:ietf:params:xml:ns:xmpp-stanzas">>, - __IgnoreEls, _el)); + __IgnoreEls, _el), + __Els); _ -> decode_error_els(__TopXMLNS, __IgnoreEls, _els, Text, - Reason) + Reason, __Els) end; decode_error_els(__TopXMLNS, __IgnoreEls, [{xmlel, <<"gone">>, _attrs, _} = _el | _els], Text, - Reason) -> + Reason, __Els) -> case get_attr(<<"xmlns">>, _attrs) of <<"urn:ietf:params:xml:ns:xmpp-stanzas">> -> decode_error_els(__TopXMLNS, __IgnoreEls, _els, Text, decode_error_gone(<<"urn:ietf:params:xml:ns:xmpp-stanzas">>, - __IgnoreEls, _el)); + __IgnoreEls, _el), + __Els); _ -> decode_error_els(__TopXMLNS, __IgnoreEls, _els, Text, - Reason) + Reason, __Els) end; decode_error_els(__TopXMLNS, __IgnoreEls, [{xmlel, <<"internal-server-error">>, _attrs, _} = _el | _els], - Text, Reason) -> + Text, Reason, __Els) -> case get_attr(<<"xmlns">>, _attrs) of <<"urn:ietf:params:xml:ns:xmpp-stanzas">> -> decode_error_els(__TopXMLNS, __IgnoreEls, _els, Text, decode_error_internal_server_error(<<"urn:ietf:params:xml:ns:xmpp-stanzas">>, - __IgnoreEls, - _el)); + __IgnoreEls, _el), + __Els); _ -> decode_error_els(__TopXMLNS, __IgnoreEls, _els, Text, - Reason) + Reason, __Els) end; decode_error_els(__TopXMLNS, __IgnoreEls, [{xmlel, <<"item-not-found">>, _attrs, _} = _el | _els], - Text, Reason) -> + Text, Reason, __Els) -> case get_attr(<<"xmlns">>, _attrs) of <<"urn:ietf:params:xml:ns:xmpp-stanzas">> -> decode_error_els(__TopXMLNS, __IgnoreEls, _els, Text, decode_error_item_not_found(<<"urn:ietf:params:xml:ns:xmpp-stanzas">>, - __IgnoreEls, _el)); + __IgnoreEls, _el), + __Els); _ -> decode_error_els(__TopXMLNS, __IgnoreEls, _els, Text, - Reason) + Reason, __Els) end; decode_error_els(__TopXMLNS, __IgnoreEls, [{xmlel, <<"jid-malformed">>, _attrs, _} = _el | _els], - Text, Reason) -> + Text, Reason, __Els) -> case get_attr(<<"xmlns">>, _attrs) of <<"urn:ietf:params:xml:ns:xmpp-stanzas">> -> decode_error_els(__TopXMLNS, __IgnoreEls, _els, Text, decode_error_jid_malformed(<<"urn:ietf:params:xml:ns:xmpp-stanzas">>, - __IgnoreEls, _el)); + __IgnoreEls, _el), + __Els); _ -> decode_error_els(__TopXMLNS, __IgnoreEls, _els, Text, - Reason) + Reason, __Els) end; decode_error_els(__TopXMLNS, __IgnoreEls, [{xmlel, <<"not-acceptable">>, _attrs, _} = _el | _els], - Text, Reason) -> + Text, Reason, __Els) -> case get_attr(<<"xmlns">>, _attrs) of <<"urn:ietf:params:xml:ns:xmpp-stanzas">> -> decode_error_els(__TopXMLNS, __IgnoreEls, _els, Text, decode_error_not_acceptable(<<"urn:ietf:params:xml:ns:xmpp-stanzas">>, - __IgnoreEls, _el)); + __IgnoreEls, _el), + __Els); _ -> decode_error_els(__TopXMLNS, __IgnoreEls, _els, Text, - Reason) + Reason, __Els) end; decode_error_els(__TopXMLNS, __IgnoreEls, [{xmlel, <<"not-allowed">>, _attrs, _} = _el | _els], - Text, Reason) -> + Text, Reason, __Els) -> case get_attr(<<"xmlns">>, _attrs) of <<"urn:ietf:params:xml:ns:xmpp-stanzas">> -> decode_error_els(__TopXMLNS, __IgnoreEls, _els, Text, decode_error_not_allowed(<<"urn:ietf:params:xml:ns:xmpp-stanzas">>, - __IgnoreEls, _el)); + __IgnoreEls, _el), + __Els); _ -> decode_error_els(__TopXMLNS, __IgnoreEls, _els, Text, - Reason) + Reason, __Els) end; decode_error_els(__TopXMLNS, __IgnoreEls, [{xmlel, <<"not-authorized">>, _attrs, _} = _el | _els], - Text, Reason) -> + Text, Reason, __Els) -> case get_attr(<<"xmlns">>, _attrs) of <<"urn:ietf:params:xml:ns:xmpp-stanzas">> -> decode_error_els(__TopXMLNS, __IgnoreEls, _els, Text, decode_error_not_authorized(<<"urn:ietf:params:xml:ns:xmpp-stanzas">>, - __IgnoreEls, _el)); + __IgnoreEls, _el), + __Els); _ -> decode_error_els(__TopXMLNS, __IgnoreEls, _els, Text, - Reason) + Reason, __Els) end; decode_error_els(__TopXMLNS, __IgnoreEls, [{xmlel, <<"payment-required">>, _attrs, _} = _el | _els], - Text, Reason) -> + Text, Reason, __Els) -> case get_attr(<<"xmlns">>, _attrs) of <<"urn:ietf:params:xml:ns:xmpp-stanzas">> -> decode_error_els(__TopXMLNS, __IgnoreEls, _els, Text, decode_error_payment_required(<<"urn:ietf:params:xml:ns:xmpp-stanzas">>, - __IgnoreEls, _el)); + __IgnoreEls, _el), + __Els); _ -> decode_error_els(__TopXMLNS, __IgnoreEls, _els, Text, - Reason) + Reason, __Els) end; decode_error_els(__TopXMLNS, __IgnoreEls, [{xmlel, <<"policy-violation">>, _attrs, _} = _el | _els], - Text, Reason) -> + Text, Reason, __Els) -> case get_attr(<<"xmlns">>, _attrs) of <<"urn:ietf:params:xml:ns:xmpp-stanzas">> -> decode_error_els(__TopXMLNS, __IgnoreEls, _els, Text, decode_error_policy_violation(<<"urn:ietf:params:xml:ns:xmpp-stanzas">>, - __IgnoreEls, _el)); + __IgnoreEls, _el), + __Els); _ -> decode_error_els(__TopXMLNS, __IgnoreEls, _els, Text, - Reason) + Reason, __Els) end; decode_error_els(__TopXMLNS, __IgnoreEls, [{xmlel, <<"recipient-unavailable">>, _attrs, _} = _el | _els], - Text, Reason) -> + Text, Reason, __Els) -> case get_attr(<<"xmlns">>, _attrs) of <<"urn:ietf:params:xml:ns:xmpp-stanzas">> -> decode_error_els(__TopXMLNS, __IgnoreEls, _els, Text, decode_error_recipient_unavailable(<<"urn:ietf:params:xml:ns:xmpp-stanzas">>, - __IgnoreEls, - _el)); + __IgnoreEls, _el), + __Els); _ -> decode_error_els(__TopXMLNS, __IgnoreEls, _els, Text, - Reason) + Reason, __Els) end; decode_error_els(__TopXMLNS, __IgnoreEls, [{xmlel, <<"redirect">>, _attrs, _} = _el | _els], Text, - Reason) -> + Reason, __Els) -> case get_attr(<<"xmlns">>, _attrs) of <<"urn:ietf:params:xml:ns:xmpp-stanzas">> -> decode_error_els(__TopXMLNS, __IgnoreEls, _els, Text, decode_error_redirect(<<"urn:ietf:params:xml:ns:xmpp-stanzas">>, - __IgnoreEls, _el)); + __IgnoreEls, _el), + __Els); _ -> decode_error_els(__TopXMLNS, __IgnoreEls, _els, Text, - Reason) + Reason, __Els) end; decode_error_els(__TopXMLNS, __IgnoreEls, [{xmlel, <<"registration-required">>, _attrs, _} = _el | _els], - Text, Reason) -> + Text, Reason, __Els) -> case get_attr(<<"xmlns">>, _attrs) of <<"urn:ietf:params:xml:ns:xmpp-stanzas">> -> decode_error_els(__TopXMLNS, __IgnoreEls, _els, Text, decode_error_registration_required(<<"urn:ietf:params:xml:ns:xmpp-stanzas">>, - __IgnoreEls, - _el)); + __IgnoreEls, _el), + __Els); _ -> decode_error_els(__TopXMLNS, __IgnoreEls, _els, Text, - Reason) + Reason, __Els) end; decode_error_els(__TopXMLNS, __IgnoreEls, [{xmlel, <<"remote-server-not-found">>, _attrs, _} = _el | _els], - Text, Reason) -> + Text, Reason, __Els) -> case get_attr(<<"xmlns">>, _attrs) of <<"urn:ietf:params:xml:ns:xmpp-stanzas">> -> decode_error_els(__TopXMLNS, __IgnoreEls, _els, Text, decode_error_remote_server_not_found(<<"urn:ietf:params:xml:ns:xmpp-stanzas">>, __IgnoreEls, - _el)); + _el), + __Els); _ -> decode_error_els(__TopXMLNS, __IgnoreEls, _els, Text, - Reason) + Reason, __Els) end; decode_error_els(__TopXMLNS, __IgnoreEls, [{xmlel, <<"remote-server-timeout">>, _attrs, _} = _el | _els], - Text, Reason) -> + Text, Reason, __Els) -> case get_attr(<<"xmlns">>, _attrs) of <<"urn:ietf:params:xml:ns:xmpp-stanzas">> -> decode_error_els(__TopXMLNS, __IgnoreEls, _els, Text, decode_error_remote_server_timeout(<<"urn:ietf:params:xml:ns:xmpp-stanzas">>, - __IgnoreEls, - _el)); + __IgnoreEls, _el), + __Els); _ -> decode_error_els(__TopXMLNS, __IgnoreEls, _els, Text, - Reason) + Reason, __Els) end; decode_error_els(__TopXMLNS, __IgnoreEls, [{xmlel, <<"resource-constraint">>, _attrs, _} = _el | _els], - Text, Reason) -> + Text, Reason, __Els) -> case get_attr(<<"xmlns">>, _attrs) of <<"urn:ietf:params:xml:ns:xmpp-stanzas">> -> decode_error_els(__TopXMLNS, __IgnoreEls, _els, Text, decode_error_resource_constraint(<<"urn:ietf:params:xml:ns:xmpp-stanzas">>, - __IgnoreEls, _el)); + __IgnoreEls, _el), + __Els); _ -> decode_error_els(__TopXMLNS, __IgnoreEls, _els, Text, - Reason) + Reason, __Els) end; decode_error_els(__TopXMLNS, __IgnoreEls, [{xmlel, <<"service-unavailable">>, _attrs, _} = _el | _els], - Text, Reason) -> + Text, Reason, __Els) -> case get_attr(<<"xmlns">>, _attrs) of <<"urn:ietf:params:xml:ns:xmpp-stanzas">> -> decode_error_els(__TopXMLNS, __IgnoreEls, _els, Text, decode_error_service_unavailable(<<"urn:ietf:params:xml:ns:xmpp-stanzas">>, - __IgnoreEls, _el)); + __IgnoreEls, _el), + __Els); _ -> decode_error_els(__TopXMLNS, __IgnoreEls, _els, Text, - Reason) + Reason, __Els) end; decode_error_els(__TopXMLNS, __IgnoreEls, [{xmlel, <<"subscription-required">>, _attrs, _} = _el | _els], - Text, Reason) -> + Text, Reason, __Els) -> case get_attr(<<"xmlns">>, _attrs) of <<"urn:ietf:params:xml:ns:xmpp-stanzas">> -> decode_error_els(__TopXMLNS, __IgnoreEls, _els, Text, decode_error_subscription_required(<<"urn:ietf:params:xml:ns:xmpp-stanzas">>, - __IgnoreEls, - _el)); + __IgnoreEls, _el), + __Els); _ -> decode_error_els(__TopXMLNS, __IgnoreEls, _els, Text, - Reason) + Reason, __Els) end; decode_error_els(__TopXMLNS, __IgnoreEls, [{xmlel, <<"undefined-condition">>, _attrs, _} = _el | _els], - Text, Reason) -> + Text, Reason, __Els) -> case get_attr(<<"xmlns">>, _attrs) of <<"urn:ietf:params:xml:ns:xmpp-stanzas">> -> decode_error_els(__TopXMLNS, __IgnoreEls, _els, Text, decode_error_undefined_condition(<<"urn:ietf:params:xml:ns:xmpp-stanzas">>, - __IgnoreEls, _el)); + __IgnoreEls, _el), + __Els); _ -> decode_error_els(__TopXMLNS, __IgnoreEls, _els, Text, - Reason) + Reason, __Els) end; decode_error_els(__TopXMLNS, __IgnoreEls, [{xmlel, <<"unexpected-request">>, _attrs, _} = _el | _els], - Text, Reason) -> + Text, Reason, __Els) -> case get_attr(<<"xmlns">>, _attrs) of <<"urn:ietf:params:xml:ns:xmpp-stanzas">> -> decode_error_els(__TopXMLNS, __IgnoreEls, _els, Text, decode_error_unexpected_request(<<"urn:ietf:params:xml:ns:xmpp-stanzas">>, - __IgnoreEls, _el)); + __IgnoreEls, _el), + __Els); _ -> decode_error_els(__TopXMLNS, __IgnoreEls, _els, Text, - Reason) + Reason, __Els) + end; +decode_error_els(__TopXMLNS, __IgnoreEls, + [{xmlel, _, _, _} = _el | _els], Text, Reason, __Els) -> + if __IgnoreEls -> + decode_error_els(__TopXMLNS, __IgnoreEls, _els, Text, + Reason, [_el | __Els]); + true -> + case is_known_tag(_el) of + true -> + decode_error_els(__TopXMLNS, __IgnoreEls, _els, Text, + Reason, [decode(_el) | __Els]); + false -> + decode_error_els(__TopXMLNS, __IgnoreEls, _els, Text, + Reason, __Els) + end end; decode_error_els(__TopXMLNS, __IgnoreEls, [_ | _els], - Text, Reason) -> + Text, Reason, __Els) -> decode_error_els(__TopXMLNS, __IgnoreEls, _els, Text, - Reason). + Reason, __Els). decode_error_attrs(__TopXMLNS, [{<<"type">>, _val} | _attrs], _Type, Code, By) -> @@ -23677,11 +23695,13 @@ decode_error_attrs(__TopXMLNS, [], Type, Code, By) -> decode_error_attr_code(__TopXMLNS, Code), decode_error_attr_by(__TopXMLNS, By)}. -encode_error({error, Type, Code, By, Reason, Text}, +encode_error({error, Type, Code, By, Reason, Text, + __Els}, _xmlns_attrs) -> - _els = lists:reverse('encode_error_$text'(Text, - 'encode_error_$reason'(Reason, - []))), + _els = [encode(_el) || _el <- __Els] ++ + lists:reverse('encode_error_$text'(Text, + 'encode_error_$reason'(Reason, + []))), _attrs = encode_error_attr_by(By, encode_error_attr_code(Code, encode_error_attr_type(Type, @@ -24212,119 +24232,100 @@ encode_error_bad_request('bad-request', _xmlns_attrs) -> decode_presence(__TopXMLNS, __IgnoreEls, {xmlel, <<"presence">>, _attrs, _els}) -> - {Error, Status, Show, Priority, __Els} = - decode_presence_els(__TopXMLNS, __IgnoreEls, _els, - undefined, [], undefined, undefined, []), + {Status, Show, Priority, __Els} = + decode_presence_els(__TopXMLNS, __IgnoreEls, _els, [], + undefined, undefined, []), {Id, Type, From, To, Lang} = decode_presence_attrs(__TopXMLNS, _attrs, undefined, undefined, undefined, undefined, undefined), {presence, Id, Type, Lang, From, To, Show, Status, - Priority, Error, __Els}. + Priority, __Els}. -decode_presence_els(__TopXMLNS, __IgnoreEls, [], Error, - Status, Show, Priority, __Els) -> - {Error, lists:reverse(Status), Show, Priority, +decode_presence_els(__TopXMLNS, __IgnoreEls, [], Status, + Show, Priority, __Els) -> + {lists:reverse(Status), Show, Priority, lists:reverse(__Els)}; decode_presence_els(__TopXMLNS, __IgnoreEls, - [{xmlel, <<"error">>, _attrs, _} = _el | _els], Error, - Status, Show, Priority, __Els) -> + [{xmlel, <<"show">>, _attrs, _} = _el | _els], Status, + Show, Priority, __Els) -> case get_attr(<<"xmlns">>, _attrs) of <<"">> when __TopXMLNS == <<"jabber:client">> -> decode_presence_els(__TopXMLNS, __IgnoreEls, _els, - decode_error(__TopXMLNS, __IgnoreEls, _el), - Status, Show, Priority, __Els); - <<"jabber:client">> -> - decode_presence_els(__TopXMLNS, __IgnoreEls, _els, - decode_error(<<"jabber:client">>, __IgnoreEls, - _el), - Status, Show, Priority, __Els); - _ -> - decode_presence_els(__TopXMLNS, __IgnoreEls, _els, - Error, Status, Show, Priority, __Els) - end; -decode_presence_els(__TopXMLNS, __IgnoreEls, - [{xmlel, <<"show">>, _attrs, _} = _el | _els], Error, - Status, Show, Priority, __Els) -> - case get_attr(<<"xmlns">>, _attrs) of - <<"">> when __TopXMLNS == <<"jabber:client">> -> - decode_presence_els(__TopXMLNS, __IgnoreEls, _els, - Error, Status, + Status, decode_presence_show(__TopXMLNS, __IgnoreEls, _el), Priority, __Els); <<"jabber:client">> -> decode_presence_els(__TopXMLNS, __IgnoreEls, _els, - Error, Status, + Status, decode_presence_show(<<"jabber:client">>, __IgnoreEls, _el), Priority, __Els); _ -> decode_presence_els(__TopXMLNS, __IgnoreEls, _els, - Error, Status, Show, Priority, __Els) + Status, Show, Priority, __Els) end; decode_presence_els(__TopXMLNS, __IgnoreEls, - [{xmlel, <<"status">>, _attrs, _} = _el | _els], Error, - Status, Show, Priority, __Els) -> + [{xmlel, <<"status">>, _attrs, _} = _el | _els], Status, + Show, Priority, __Els) -> case get_attr(<<"xmlns">>, _attrs) of <<"">> when __TopXMLNS == <<"jabber:client">> -> decode_presence_els(__TopXMLNS, __IgnoreEls, _els, - Error, [decode_presence_status(__TopXMLNS, __IgnoreEls, _el) | Status], Show, Priority, __Els); <<"jabber:client">> -> decode_presence_els(__TopXMLNS, __IgnoreEls, _els, - Error, [decode_presence_status(<<"jabber:client">>, __IgnoreEls, _el) | Status], Show, Priority, __Els); _ -> decode_presence_els(__TopXMLNS, __IgnoreEls, _els, - Error, Status, Show, Priority, __Els) + Status, Show, Priority, __Els) end; decode_presence_els(__TopXMLNS, __IgnoreEls, [{xmlel, <<"priority">>, _attrs, _} = _el | _els], - Error, Status, Show, Priority, __Els) -> + Status, Show, Priority, __Els) -> case get_attr(<<"xmlns">>, _attrs) of <<"">> when __TopXMLNS == <<"jabber:client">> -> decode_presence_els(__TopXMLNS, __IgnoreEls, _els, - Error, Status, Show, + Status, Show, decode_presence_priority(__TopXMLNS, __IgnoreEls, _el), __Els); <<"jabber:client">> -> decode_presence_els(__TopXMLNS, __IgnoreEls, _els, - Error, Status, Show, + Status, Show, decode_presence_priority(<<"jabber:client">>, __IgnoreEls, _el), __Els); _ -> decode_presence_els(__TopXMLNS, __IgnoreEls, _els, - Error, Status, Show, Priority, __Els) + Status, Show, Priority, __Els) end; decode_presence_els(__TopXMLNS, __IgnoreEls, - [{xmlel, _, _, _} = _el | _els], Error, Status, Show, - Priority, __Els) -> + [{xmlel, _, _, _} = _el | _els], Status, Show, Priority, + __Els) -> if __IgnoreEls -> decode_presence_els(__TopXMLNS, __IgnoreEls, _els, - Error, Status, Show, Priority, [_el | __Els]); + Status, Show, Priority, [_el | __Els]); true -> case is_known_tag(_el) of true -> decode_presence_els(__TopXMLNS, __IgnoreEls, _els, - Error, Status, Show, Priority, + Status, Show, Priority, [decode(_el) | __Els]); false -> decode_presence_els(__TopXMLNS, __IgnoreEls, _els, - Error, Status, Show, Priority, __Els) + Status, Show, Priority, __Els) end end; decode_presence_els(__TopXMLNS, __IgnoreEls, [_ | _els], - Error, Status, Show, Priority, __Els) -> + Status, Show, Priority, __Els) -> decode_presence_els(__TopXMLNS, __IgnoreEls, _els, - Error, Status, Show, Priority, __Els). + Status, Show, Priority, __Els). decode_presence_attrs(__TopXMLNS, [{<<"id">>, _val} | _attrs], _Id, Type, From, To, @@ -24364,14 +24365,13 @@ decode_presence_attrs(__TopXMLNS, [], Id, Type, From, 'decode_presence_attr_xml:lang'(__TopXMLNS, Lang)}. encode_presence({presence, Id, Type, Lang, From, To, - Show, Status, Priority, Error, __Els}, + Show, Status, Priority, __Els}, _xmlns_attrs) -> _els = [encode(_el) || _el <- __Els] ++ - lists:reverse('encode_presence_$error'(Error, - 'encode_presence_$status'(Status, - 'encode_presence_$show'(Show, - 'encode_presence_$priority'(Priority, - []))))), + lists:reverse('encode_presence_$status'(Status, + 'encode_presence_$show'(Show, + 'encode_presence_$priority'(Priority, + [])))), _attrs = 'encode_presence_attr_xml:lang'(Lang, encode_presence_attr_to(To, encode_presence_attr_from(From, @@ -24380,10 +24380,6 @@ encode_presence({presence, Id, Type, Lang, From, To, _xmlns_attrs))))), {xmlel, <<"presence">>, _attrs, _els}. -'encode_presence_$error'(undefined, _acc) -> _acc; -'encode_presence_$error'(Error, _acc) -> - [encode_error(Error, []) | _acc]. - 'encode_presence_$status'([], _acc) -> _acc; 'encode_presence_$status'([Status | _els], _acc) -> 'encode_presence_$status'(_els, @@ -24598,117 +24594,100 @@ encode_presence_show_cdata(_val, _acc) -> decode_message(__TopXMLNS, __IgnoreEls, {xmlel, <<"message">>, _attrs, _els}) -> - {Error, Thread, Subject, Body, __Els} = + {Thread, Subject, Body, __Els} = decode_message_els(__TopXMLNS, __IgnoreEls, _els, - undefined, undefined, [], [], []), + undefined, [], [], []), {Id, Type, From, To, Lang} = decode_message_attrs(__TopXMLNS, _attrs, undefined, undefined, undefined, undefined, undefined), {message, Id, Type, Lang, From, To, Subject, Body, - Thread, Error, __Els}. + Thread, __Els}. -decode_message_els(__TopXMLNS, __IgnoreEls, [], Error, - Thread, Subject, Body, __Els) -> - {Error, Thread, lists:reverse(Subject), - lists:reverse(Body), lists:reverse(__Els)}; +decode_message_els(__TopXMLNS, __IgnoreEls, [], Thread, + Subject, Body, __Els) -> + {Thread, lists:reverse(Subject), lists:reverse(Body), + lists:reverse(__Els)}; decode_message_els(__TopXMLNS, __IgnoreEls, - [{xmlel, <<"error">>, _attrs, _} = _el | _els], Error, + [{xmlel, <<"subject">>, _attrs, _} = _el | _els], Thread, Subject, Body, __Els) -> case get_attr(<<"xmlns">>, _attrs) of <<"">> when __TopXMLNS == <<"jabber:client">> -> decode_message_els(__TopXMLNS, __IgnoreEls, _els, - decode_error(__TopXMLNS, __IgnoreEls, _el), Thread, - Subject, Body, __Els); - <<"jabber:client">> -> - decode_message_els(__TopXMLNS, __IgnoreEls, _els, - decode_error(<<"jabber:client">>, __IgnoreEls, - _el), - Thread, Subject, Body, __Els); - _ -> - decode_message_els(__TopXMLNS, __IgnoreEls, _els, Error, - Thread, Subject, Body, __Els) - end; -decode_message_els(__TopXMLNS, __IgnoreEls, - [{xmlel, <<"subject">>, _attrs, _} = _el | _els], Error, - Thread, Subject, Body, __Els) -> - case get_attr(<<"xmlns">>, _attrs) of - <<"">> when __TopXMLNS == <<"jabber:client">> -> - decode_message_els(__TopXMLNS, __IgnoreEls, _els, Error, Thread, [decode_message_subject(__TopXMLNS, __IgnoreEls, _el) | Subject], Body, __Els); <<"jabber:client">> -> - decode_message_els(__TopXMLNS, __IgnoreEls, _els, Error, + decode_message_els(__TopXMLNS, __IgnoreEls, _els, Thread, [decode_message_subject(<<"jabber:client">>, __IgnoreEls, _el) | Subject], Body, __Els); _ -> - decode_message_els(__TopXMLNS, __IgnoreEls, _els, Error, + decode_message_els(__TopXMLNS, __IgnoreEls, _els, Thread, Subject, Body, __Els) end; decode_message_els(__TopXMLNS, __IgnoreEls, - [{xmlel, <<"thread">>, _attrs, _} = _el | _els], Error, - Thread, Subject, Body, __Els) -> + [{xmlel, <<"thread">>, _attrs, _} = _el | _els], Thread, + Subject, Body, __Els) -> case get_attr(<<"xmlns">>, _attrs) of <<"">> when __TopXMLNS == <<"jabber:client">> -> - decode_message_els(__TopXMLNS, __IgnoreEls, _els, Error, + decode_message_els(__TopXMLNS, __IgnoreEls, _els, decode_message_thread(__TopXMLNS, __IgnoreEls, _el), Subject, Body, __Els); <<"jabber:client">> -> - decode_message_els(__TopXMLNS, __IgnoreEls, _els, Error, + decode_message_els(__TopXMLNS, __IgnoreEls, _els, decode_message_thread(<<"jabber:client">>, __IgnoreEls, _el), Subject, Body, __Els); _ -> - decode_message_els(__TopXMLNS, __IgnoreEls, _els, Error, + decode_message_els(__TopXMLNS, __IgnoreEls, _els, Thread, Subject, Body, __Els) end; decode_message_els(__TopXMLNS, __IgnoreEls, - [{xmlel, <<"body">>, _attrs, _} = _el | _els], Error, - Thread, Subject, Body, __Els) -> + [{xmlel, <<"body">>, _attrs, _} = _el | _els], Thread, + Subject, Body, __Els) -> case get_attr(<<"xmlns">>, _attrs) of <<"">> when __TopXMLNS == <<"jabber:client">> -> - decode_message_els(__TopXMLNS, __IgnoreEls, _els, Error, + decode_message_els(__TopXMLNS, __IgnoreEls, _els, Thread, Subject, [decode_message_body(__TopXMLNS, __IgnoreEls, _el) | Body], __Els); <<"jabber:client">> -> - decode_message_els(__TopXMLNS, __IgnoreEls, _els, Error, + decode_message_els(__TopXMLNS, __IgnoreEls, _els, Thread, Subject, [decode_message_body(<<"jabber:client">>, __IgnoreEls, _el) | Body], __Els); _ -> - decode_message_els(__TopXMLNS, __IgnoreEls, _els, Error, + decode_message_els(__TopXMLNS, __IgnoreEls, _els, Thread, Subject, Body, __Els) end; decode_message_els(__TopXMLNS, __IgnoreEls, - [{xmlel, _, _, _} = _el | _els], Error, Thread, Subject, - Body, __Els) -> + [{xmlel, _, _, _} = _el | _els], Thread, Subject, Body, + __Els) -> if __IgnoreEls -> - decode_message_els(__TopXMLNS, __IgnoreEls, _els, Error, + decode_message_els(__TopXMLNS, __IgnoreEls, _els, Thread, Subject, Body, [_el | __Els]); true -> case is_known_tag(_el) of true -> - decode_message_els(__TopXMLNS, __IgnoreEls, _els, Error, + decode_message_els(__TopXMLNS, __IgnoreEls, _els, Thread, Subject, Body, [decode(_el) | __Els]); false -> - decode_message_els(__TopXMLNS, __IgnoreEls, _els, Error, + decode_message_els(__TopXMLNS, __IgnoreEls, _els, Thread, Subject, Body, __Els) end end; decode_message_els(__TopXMLNS, __IgnoreEls, [_ | _els], - Error, Thread, Subject, Body, __Els) -> - decode_message_els(__TopXMLNS, __IgnoreEls, _els, Error, + Thread, Subject, Body, __Els) -> + decode_message_els(__TopXMLNS, __IgnoreEls, _els, Thread, Subject, Body, __Els). decode_message_attrs(__TopXMLNS, @@ -24749,14 +24728,13 @@ decode_message_attrs(__TopXMLNS, [], Id, Type, From, To, 'decode_message_attr_xml:lang'(__TopXMLNS, Lang)}. encode_message({message, Id, Type, Lang, From, To, - Subject, Body, Thread, Error, __Els}, + Subject, Body, Thread, __Els}, _xmlns_attrs) -> _els = [encode(_el) || _el <- __Els] ++ - lists:reverse('encode_message_$error'(Error, - 'encode_message_$thread'(Thread, - 'encode_message_$subject'(Subject, - 'encode_message_$body'(Body, - []))))), + lists:reverse('encode_message_$thread'(Thread, + 'encode_message_$subject'(Subject, + 'encode_message_$body'(Body, + [])))), _attrs = 'encode_message_attr_xml:lang'(Lang, encode_message_attr_to(To, encode_message_attr_from(From, @@ -24765,10 +24743,6 @@ encode_message({message, Id, Type, Lang, From, To, _xmlns_attrs))))), {xmlel, <<"message">>, _attrs, _els}. -'encode_message_$error'(undefined, _acc) -> _acc; -'encode_message_$error'(Error, _acc) -> - [encode_error(Error, []) | _acc]. - 'encode_message_$thread'(undefined, _acc) -> _acc; 'encode_message_$thread'(Thread, _acc) -> [encode_message_thread(Thread, []) | _acc]. @@ -24991,51 +24965,33 @@ encode_message_subject_cdata(_val, _acc) -> decode_iq(__TopXMLNS, __IgnoreEls, {xmlel, <<"iq">>, _attrs, _els}) -> - {Error, __Els} = decode_iq_els(__TopXMLNS, __IgnoreEls, - _els, undefined, []), + __Els = decode_iq_els(__TopXMLNS, __IgnoreEls, _els, + []), {Id, Type, From, To, Lang} = decode_iq_attrs(__TopXMLNS, _attrs, undefined, undefined, undefined, undefined, undefined), - {iq, Id, Type, Lang, From, To, Error, __Els}. + {iq, Id, Type, Lang, From, To, __Els}. -decode_iq_els(__TopXMLNS, __IgnoreEls, [], Error, - __Els) -> - {Error, lists:reverse(__Els)}; +decode_iq_els(__TopXMLNS, __IgnoreEls, [], __Els) -> + lists:reverse(__Els); decode_iq_els(__TopXMLNS, __IgnoreEls, - [{xmlel, <<"error">>, _attrs, _} = _el | _els], Error, - __Els) -> - case get_attr(<<"xmlns">>, _attrs) of - <<"">> when __TopXMLNS == <<"jabber:client">> -> - decode_iq_els(__TopXMLNS, __IgnoreEls, _els, - decode_error(__TopXMLNS, __IgnoreEls, _el), __Els); - <<"jabber:client">> -> - decode_iq_els(__TopXMLNS, __IgnoreEls, _els, - decode_error(<<"jabber:client">>, __IgnoreEls, _el), - __Els); - _ -> - decode_iq_els(__TopXMLNS, __IgnoreEls, _els, Error, - __Els) - end; -decode_iq_els(__TopXMLNS, __IgnoreEls, - [{xmlel, _, _, _} = _el | _els], Error, __Els) -> + [{xmlel, _, _, _} = _el | _els], __Els) -> if __IgnoreEls -> - decode_iq_els(__TopXMLNS, __IgnoreEls, _els, Error, + decode_iq_els(__TopXMLNS, __IgnoreEls, _els, [_el | __Els]); true -> case is_known_tag(_el) of true -> - decode_iq_els(__TopXMLNS, __IgnoreEls, _els, Error, + decode_iq_els(__TopXMLNS, __IgnoreEls, _els, [decode(_el) | __Els]); false -> - decode_iq_els(__TopXMLNS, __IgnoreEls, _els, Error, - __Els) + decode_iq_els(__TopXMLNS, __IgnoreEls, _els, __Els) end end; decode_iq_els(__TopXMLNS, __IgnoreEls, [_ | _els], - Error, __Els) -> - decode_iq_els(__TopXMLNS, __IgnoreEls, _els, Error, - __Els). + __Els) -> + decode_iq_els(__TopXMLNS, __IgnoreEls, _els, __Els). decode_iq_attrs(__TopXMLNS, [{<<"id">>, _val} | _attrs], _Id, Type, From, To, Lang) -> @@ -25072,10 +25028,9 @@ decode_iq_attrs(__TopXMLNS, [], Id, Type, From, To, decode_iq_attr_to(__TopXMLNS, To), 'decode_iq_attr_xml:lang'(__TopXMLNS, Lang)}. -encode_iq({iq, Id, Type, Lang, From, To, Error, __Els}, +encode_iq({iq, Id, Type, Lang, From, To, __Els}, _xmlns_attrs) -> - _els = [encode(_el) || _el <- __Els] ++ - lists:reverse('encode_iq_$error'(Error, [])), + _els = [encode(_el) || _el <- __Els], _attrs = 'encode_iq_attr_xml:lang'(Lang, encode_iq_attr_to(To, encode_iq_attr_from(From, @@ -25084,10 +25039,6 @@ encode_iq({iq, Id, Type, Lang, From, To, Error, __Els}, _xmlns_attrs))))), {xmlel, <<"iq">>, _attrs, _els}. -'encode_iq_$error'(undefined, _acc) -> _acc; -'encode_iq_$error'(Error, _acc) -> - [encode_error(Error, []) | _acc]. - decode_iq_attr_id(__TopXMLNS, undefined) -> erlang:error({xmpp_codec, {missing_attr, <<"id">>, <<"iq">>, __TopXMLNS}}); diff --git a/tools/xmpp_codec.spec b/tools/xmpp_codec.spec index 293f12d17..964b631c2 100644 --- a/tools/xmpp_codec.spec +++ b/tools/xmpp_codec.spec @@ -316,8 +316,7 @@ -xml(iq, #elem{name = <<"iq">>, xmlns = <<"jabber:client">>, - result = {iq, '$id', '$type', '$lang', '$from', '$to', - '$error', '$_els'}, + result = {iq, '$id', '$type', '$lang', '$from', '$to', '$_els'}, attrs = [#attr{name = <<"id">>, required = true}, #attr{name = <<"type">>, @@ -331,8 +330,7 @@ dec = {dec_jid, []}, enc = {enc_jid, []}}, #attr{name = <<"xml:lang">>, - label = '$lang'}], - refs = [#ref{name = error, min = 0, max = 1, label = '$error'}]}). + label = '$lang'}]}). -xml(message_subject, #elem{name = <<"subject">>, @@ -357,7 +355,7 @@ #elem{name = <<"message">>, xmlns = <<"jabber:client">>, result = {message, '$id', '$type', '$lang', '$from', '$to', - '$subject', '$body', '$thread', '$error', '$_els'}, + '$subject', '$body', '$thread', '$_els'}, attrs = [#attr{name = <<"id">>}, #attr{name = <<"type">>, default = normal, @@ -372,8 +370,7 @@ enc = {enc_jid, []}}, #attr{name = <<"xml:lang">>, label = '$lang'}], - refs = [#ref{name = error, min = 0, max = 1, label = '$error'}, - #ref{name = message_subject, label = '$subject'}, + refs = [#ref{name = message_subject, label = '$subject'}, #ref{name = message_thread, min = 0, max = 1, label = '$thread'}, #ref{name = message_body, label = '$body'}]}). @@ -403,7 +400,7 @@ #elem{name = <<"presence">>, xmlns = <<"jabber:client">>, result = {presence, '$id', '$type', '$lang', '$from', '$to', - '$show', '$status', '$priority', '$error', '$_els'}, + '$show', '$status', '$priority', '$_els'}, attrs = [#attr{name = <<"id">>}, #attr{name = <<"type">>, default = available, @@ -419,8 +416,7 @@ enc = {enc_jid, []}}, #attr{name = <<"xml:lang">>, label = '$lang'}], - refs = [#ref{name = error, min = 0, max = 1, label = '$error'}, - #ref{name = presence_show, min = 0, max = 1, label = '$show'}, + refs = [#ref{name = presence_show, min = 0, max = 1, label = '$show'}, #ref{name = presence_status, label = '$status'}, #ref{name = presence_priority, min = 0, max = 1, label = '$priority'}]}). @@ -531,7 +527,7 @@ -xml(error, #elem{name = <<"error">>, xmlns = <<"jabber:client">>, - result = {error, '$type', '$code', '$by', '$reason', '$text'}, + result = {error, '$type', '$code', '$by', '$reason', '$text', '$_els'}, attrs = [#attr{name = <<"type">>, label = '$type', required = true, @@ -2880,8 +2876,7 @@ -xml(db_result, #elem{name = <<"db:result">>, xmlns = <<"jabber:client">>, - result = {db_result, '$from', '$to', '$type', '$key', '$error'}, - refs = [#ref{name = error, min = 0, max = 1}], + result = {db_result, '$from', '$to', '$type', '$key', '$_els'}, cdata = #cdata{default = <<"">>, label = '$key'}, attrs = [#attr{name = <<"from">>, required = true, dec = {dec_jid, []}, enc = {enc_jid, []}}, @@ -2894,8 +2889,7 @@ -xml(db_verify, #elem{name = <<"db:verify">>, xmlns = <<"jabber:client">>, - result = {db_verify, '$from', '$to', '$id', '$type', '$key', '$error'}, - refs = [#ref{name = error, min = 0, max = 1}], + result = {db_verify, '$from', '$to', '$id', '$type', '$key', '$_els'}, cdata = #cdata{default = <<"">>, label = '$key'}, attrs = [#attr{name = <<"from">>, required = true, dec = {dec_jid, []}, enc = {enc_jid, []}},